devise 3.2.4 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +33 -17
  4. data/CHANGELOG.md +57 -1033
  5. data/CODE_OF_CONDUCT.md +22 -0
  6. data/CONTRIBUTING.md +2 -0
  7. data/Gemfile +5 -5
  8. data/Gemfile.lock +138 -115
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +124 -65
  11. data/Rakefile +2 -1
  12. data/app/controllers/devise/confirmations_controller.rb +7 -3
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -4
  14. data/app/controllers/devise/passwords_controller.rb +16 -6
  15. data/app/controllers/devise/registrations_controller.rb +22 -10
  16. data/app/controllers/devise/sessions_controller.rb +42 -14
  17. data/app/controllers/devise/unlocks_controller.rb +5 -2
  18. data/app/controllers/devise_controller.rb +63 -29
  19. data/app/mailers/devise/mailer.rb +4 -0
  20. data/app/views/devise/confirmations/new.html.erb +7 -3
  21. data/app/views/devise/mailer/password_change.html.erb +3 -0
  22. data/app/views/devise/passwords/edit.html.erb +14 -5
  23. data/app/views/devise/passwords/new.html.erb +7 -3
  24. data/app/views/devise/registrations/edit.html.erb +19 -9
  25. data/app/views/devise/registrations/new.html.erb +18 -7
  26. data/app/views/devise/sessions/new.html.erb +16 -7
  27. data/app/views/devise/shared/{_links.erb → _links.html.erb} +2 -2
  28. data/app/views/devise/unlocks/new.html.erb +7 -3
  29. data/bin/test +13 -0
  30. data/config/locales/en.yml +19 -16
  31. data/devise.gemspec +3 -4
  32. data/gemfiles/{Gemfile.rails-3.2-stable → Gemfile.rails-4.1-stable} +6 -6
  33. data/gemfiles/Gemfile.rails-4.1-stable.lock +167 -0
  34. data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.2-stable} +6 -6
  35. data/gemfiles/Gemfile.rails-4.2-stable.lock +189 -0
  36. data/gemfiles/Gemfile.rails-5.0-beta +37 -0
  37. data/gemfiles/Gemfile.rails-5.0-beta.lock +199 -0
  38. data/lib/devise/controllers/helpers.rb +94 -27
  39. data/lib/devise/controllers/rememberable.rb +9 -2
  40. data/lib/devise/controllers/sign_in_out.rb +2 -9
  41. data/lib/devise/controllers/store_location.rb +11 -3
  42. data/lib/devise/controllers/url_helpers.rb +7 -7
  43. data/lib/devise/encryptor.rb +22 -0
  44. data/lib/devise/failure_app.rb +72 -23
  45. data/lib/devise/hooks/activatable.rb +3 -4
  46. data/lib/devise/hooks/csrf_cleaner.rb +3 -1
  47. data/lib/devise/hooks/timeoutable.rb +13 -8
  48. data/lib/devise/mailers/helpers.rb +1 -1
  49. data/lib/devise/mapping.rb +6 -2
  50. data/lib/devise/models/authenticatable.rb +32 -28
  51. data/lib/devise/models/confirmable.rb +55 -22
  52. data/lib/devise/models/database_authenticatable.rb +32 -19
  53. data/lib/devise/models/lockable.rb +5 -5
  54. data/lib/devise/models/recoverable.rb +44 -20
  55. data/lib/devise/models/rememberable.rb +54 -27
  56. data/lib/devise/models/timeoutable.rb +0 -6
  57. data/lib/devise/models/trackable.rb +5 -3
  58. data/lib/devise/models/validatable.rb +3 -3
  59. data/lib/devise/models.rb +1 -1
  60. data/lib/devise/omniauth/url_helpers.rb +62 -4
  61. data/lib/devise/parameter_sanitizer.rb +176 -61
  62. data/lib/devise/rails/routes.rb +76 -59
  63. data/lib/devise/rails/warden_compat.rb +1 -10
  64. data/lib/devise/rails.rb +2 -11
  65. data/lib/devise/strategies/authenticatable.rb +15 -6
  66. data/lib/devise/strategies/database_authenticatable.rb +5 -4
  67. data/lib/devise/strategies/rememberable.rb +13 -3
  68. data/lib/devise/test_helpers.rb +12 -7
  69. data/lib/devise/token_generator.rb +1 -41
  70. data/lib/devise/version.rb +1 -1
  71. data/lib/devise.rb +150 -58
  72. data/lib/generators/active_record/devise_generator.rb +28 -4
  73. data/lib/generators/active_record/templates/migration.rb +3 -3
  74. data/lib/generators/active_record/templates/migration_existing.rb +3 -3
  75. data/lib/generators/devise/controllers_generator.rb +44 -0
  76. data/lib/generators/devise/install_generator.rb +15 -0
  77. data/lib/generators/devise/orm_helpers.rb +1 -18
  78. data/lib/generators/devise/views_generator.rb +14 -3
  79. data/lib/generators/templates/README +1 -1
  80. data/lib/generators/templates/controllers/README +14 -0
  81. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  82. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  83. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  84. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  85. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  86. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  87. data/lib/generators/templates/devise.rb +36 -28
  88. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  89. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  90. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  91. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  92. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  93. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  94. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +2 -2
  95. data/test/controllers/custom_registrations_controller_test.rb +40 -0
  96. data/test/controllers/custom_strategy_test.rb +7 -5
  97. data/test/controllers/helper_methods_test.rb +22 -0
  98. data/test/controllers/helpers_test.rb +41 -1
  99. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  100. data/test/controllers/internal_helpers_test.rb +19 -15
  101. data/test/controllers/load_hooks_controller_test.rb +19 -0
  102. data/test/controllers/passwords_controller_test.rb +5 -4
  103. data/test/controllers/sessions_controller_test.rb +24 -21
  104. data/test/controllers/url_helpers_test.rb +7 -1
  105. data/test/devise_test.rb +48 -8
  106. data/test/failure_app_test.rb +107 -19
  107. data/test/generators/active_record_generator_test.rb +6 -26
  108. data/test/generators/controllers_generator_test.rb +48 -0
  109. data/test/generators/install_generator_test.rb +14 -3
  110. data/test/generators/views_generator_test.rb +8 -1
  111. data/test/helpers/devise_helper_test.rb +10 -12
  112. data/test/integration/authenticatable_test.rb +37 -21
  113. data/test/integration/confirmable_test.rb +54 -14
  114. data/test/integration/database_authenticatable_test.rb +12 -1
  115. data/test/integration/http_authenticatable_test.rb +4 -5
  116. data/test/integration/lockable_test.rb +10 -9
  117. data/test/integration/omniauthable_test.rb +13 -11
  118. data/test/integration/recoverable_test.rb +28 -15
  119. data/test/integration/registerable_test.rb +41 -33
  120. data/test/integration/rememberable_test.rb +51 -7
  121. data/test/integration/timeoutable_test.rb +23 -22
  122. data/test/integration/trackable_test.rb +3 -3
  123. data/test/mailers/confirmation_instructions_test.rb +10 -10
  124. data/test/mailers/reset_password_instructions_test.rb +8 -8
  125. data/test/mailers/unlock_instructions_test.rb +8 -8
  126. data/test/mapping_test.rb +7 -0
  127. data/test/models/authenticatable_test.rb +11 -1
  128. data/test/models/confirmable_test.rb +91 -42
  129. data/test/models/database_authenticatable_test.rb +26 -6
  130. data/test/models/lockable_test.rb +29 -17
  131. data/test/models/recoverable_test.rb +74 -7
  132. data/test/models/rememberable_test.rb +68 -94
  133. data/test/models/trackable_test.rb +28 -0
  134. data/test/models/validatable_test.rb +9 -17
  135. data/test/models_test.rb +15 -6
  136. data/test/omniauth/url_helpers_test.rb +4 -7
  137. data/test/orm/active_record.rb +6 -1
  138. data/test/parameter_sanitizer_test.rb +103 -53
  139. data/test/rails_app/app/active_record/user.rb +1 -0
  140. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  141. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  142. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  143. data/test/rails_app/app/controllers/admins_controller.rb +1 -6
  144. data/test/rails_app/app/controllers/application_controller.rb +5 -2
  145. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  146. data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
  147. data/test/rails_app/app/controllers/home_controller.rb +5 -1
  148. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +3 -3
  149. data/test/rails_app/app/controllers/users_controller.rb +6 -6
  150. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  151. data/test/rails_app/app/mailers/users/mailer.rb +0 -9
  152. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  153. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  154. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  155. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  156. data/test/rails_app/config/application.rb +3 -3
  157. data/test/rails_app/config/boot.rb +4 -4
  158. data/test/rails_app/config/environments/production.rb +6 -2
  159. data/test/rails_app/config/environments/test.rb +13 -3
  160. data/test/rails_app/config/initializers/devise.rb +15 -16
  161. data/test/rails_app/config/initializers/secret_token.rb +1 -6
  162. data/test/rails_app/config/routes.rb +23 -3
  163. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -2
  164. data/test/rails_app/lib/shared_user.rb +1 -1
  165. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  166. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  167. data/test/rails_test.rb +9 -0
  168. data/test/routes_test.rb +33 -16
  169. data/test/support/assertions.rb +2 -3
  170. data/test/support/helpers.rb +13 -6
  171. data/test/support/http_method_compatibility.rb +51 -0
  172. data/test/support/integration.rb +4 -4
  173. data/test/support/webrat/integrations/rails.rb +9 -0
  174. data/test/test_helper.rb +7 -0
  175. data/test/test_helpers_test.rb +43 -38
  176. data/test/test_models.rb +3 -3
  177. metadata +77 -23
  178. data/gemfiles/Gemfile.rails-4.0-stable +0 -29
data/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  By [Plataformatec](http://plataformatec.com.br/).
4
4
 
5
- [![Build Status](https://api.travis-ci.org/plataformatec/devise.png?branch=master)](http://travis-ci.org/plataformatec/devise)
6
- [![Code Climate](https://codeclimate.com/github/plataformatec/devise.png)](https://codeclimate.com/github/plataformatec/devise)
5
+ [![Build Status](https://api.travis-ci.org/plataformatec/devise.svg?branch=master)](http://travis-ci.org/plataformatec/devise)
6
+ [![Code Climate](https://codeclimate.com/github/plataformatec/devise.svg)](https://codeclimate.com/github/plataformatec/devise)
7
7
 
8
8
  This README is [also available in a friendly navigable format](http://devise.plataformatec.com.br/).
9
9
 
@@ -12,23 +12,21 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
12
12
  * Is Rack based;
13
13
  * Is a complete MVC solution based on Rails engines;
14
14
  * Allows you to have multiple models signed in at the same time;
15
- * Is based on a modularity concept: use just what you really need.
15
+ * Is based on a modularity concept: use only what you really need.
16
16
 
17
17
  It's composed of 10 modules:
18
18
 
19
- * [Database Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable): encrypts and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
20
- * [Omniauthable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Omniauthable): adds Omniauth (https://github.com/intridea/omniauth) support.
19
+ * [Database Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable): hashes and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
20
+ * [Omniauthable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Omniauthable): adds OmniAuth (https://github.com/intridea/omniauth) support.
21
21
  * [Confirmable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Confirmable): sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
22
22
  * [Recoverable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Recoverable): resets the user password and sends reset instructions.
23
23
  * [Registerable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Registerable): handles signing up users through a registration process, also allowing them to edit and destroy their account.
24
24
  * [Rememberable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Rememberable): manages generating and clearing a token for remembering the user from a saved cookie.
25
25
  * [Trackable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Trackable): tracks sign in count, timestamps and IP address.
26
- * [Timeoutable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Timeoutable): expires sessions that have no activity in a specified period of time.
26
+ * [Timeoutable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Timeoutable): expires sessions that have not been active in a specified period of time.
27
27
  * [Validatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Validatable): provides validations of email and password. It's optional and can be customized, so you're able to define your own validations.
28
28
  * [Lockable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Lockable): locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.
29
29
 
30
- Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby is on progress.
31
-
32
30
  ## Information
33
31
 
34
32
  ### The Devise wiki
@@ -43,7 +41,7 @@ If you discover a problem with Devise, we would like to know about it. However,
43
41
 
44
42
  https://github.com/plataformatec/devise/wiki/Bug-reports
45
43
 
46
- If you found a security bug, do *NOT* use the GitHub issue tracker. Send an email to opensource@plataformatec.com.br.
44
+ If you have discovered a security related bug, please do *NOT* use the GitHub issue tracker. Send an email to opensource@plataformatec.com.br.
47
45
 
48
46
  ### Mailing list
49
47
 
@@ -81,16 +79,17 @@ You will usually want to write tests for your changes. To run the test suite, g
81
79
 
82
80
  ## Starting with Rails?
83
81
 
84
- If you are building your first Rails application, we recommend you to *not* use Devise. Devise requires a good understanding of the Rails Framework. In such cases, we advise you to start a simple authentication system from scratch, today we have two resources:
82
+ If you are building your first Rails application, we recommend you *do not* use Devise. Devise requires a good understanding of the Rails Framework. In such cases, we advise you to start a simple authentication system from scratch. Today, we have three resources that should help you get started:
85
83
 
86
- * Michael Hartl's online book: http://railstutorial.org/chapters/modeling-and-viewing-users-two#top
84
+ * Michael Hartl's online book: https://www.railstutorial.org/book/modeling_users
87
85
  * Ryan Bates' Railscast: http://railscasts.com/episodes/250-authentication-from-scratch
86
+ * Codecademy's Ruby on Rails: Authentication and Authorization: http://www.codecademy.com/en/learn/rails-auth
88
87
 
89
- Once you have solidified your understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :)
88
+ Once you have solidified your understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :smiley:
90
89
 
91
90
  ## Getting started
92
91
 
93
- Devise 3.0 works with Rails 3.2 onwards. You can add it to your Gemfile with:
92
+ Devise 4.0 works with Rails 4.2 onwards. You can add it to your Gemfile with:
94
93
 
95
94
  ```ruby
96
95
  gem 'devise'
@@ -104,30 +103,36 @@ After you install Devise and add it to your Gemfile, you need to run the generat
104
103
  rails generate devise:install
105
104
  ```
106
105
 
107
- The generator will install an initializer which describes ALL Devise's configuration options and you MUST take a look at it. When you are done, you are ready to add Devise to any of your models using the generator:
106
+ The generator will install an initializer which describes ALL of Devise's configuration options. It is *imperative* that you take a look at it. When you are done, you are ready to add Devise to any of your models using the generator:
108
107
 
109
108
  ```console
110
109
  rails generate devise MODEL
111
110
  ```
112
111
 
113
- Replace MODEL by the class name used for the applications users, it's frequently `User` but could also be `Admin`. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run `rake db:migrate` as the generator will have created a migration file (if your ORM supports them). This generator also configures your `config/routes.rb` file to point to the Devise controller.
112
+ Replace MODEL with the class name used for the application’s users (its frequently `User` but could also be `Admin`). This will create a model (if one does not exist) and configure it with the default Devise modules. The generator also configures your `config/routes.rb` file to point to the Devise controller.
113
+
114
+ Next, check the MODEL for any additional configuration options you might want to add, such as confirmable or lockable. If you add an option, be sure to inspect the migration file (created by the generator if your ORM supports them) and uncomment the appropriate section. For example, if you add the confirmable option in the model, you'll need to uncomment the Confirmable section in the migration. Then run `rake db:migrate`
114
115
 
115
- Next, you need to set up the default url options for the Devise mailer in each environment. Here is a possible configuration for `config/environments/development.rb`:
116
+ Next, you need to set up the default URL options for the Devise mailer in each environment. Here is a possible configuration for `config/environments/development.rb`:
116
117
 
117
118
  ```ruby
118
- config.action_mailer.default_url_options = { host: 'localhost:3000' }
119
+ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
119
120
  ```
120
121
 
121
- You should restart your application after changing Devise's configuration options. Otherwise you'll run into strange errors like users being unable to login and route helpers being undefined.
122
+ You should restart your application after changing Devise's configuration options. Otherwise, you will run into strange errors, for example, users being unable to login and route helpers being undefined.
122
123
 
123
124
  ### Controller filters and helpers
124
125
 
125
- Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_filter:
126
+ Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_action (assuming your devise model is 'User'):
126
127
 
127
128
  ```ruby
128
- before_filter :authenticate_user!
129
+ before_action :authenticate_user!
129
130
  ```
130
131
 
132
+ For Rails 5, note that `protect_from_forgery` is no longer prepended to the `before_action` chain, so if you have set `authenticate_user` before `protect_from_forgery`, your request will result in "Can't verify CSRF token authenticity." To resolve this, either change the order in which you call them, or use `protect_from_forgery prepend: true`.
133
+
134
+ If your devise model is something other than User, replace "_user" with "_yourmodel". The same logic applies to the instructions below.
135
+
131
136
  To verify if a user is signed in, use the following helper:
132
137
 
133
138
  ```ruby
@@ -146,7 +151,7 @@ You can access the session for this scope:
146
151
  user_session
147
152
  ```
148
153
 
149
- After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect. For instance, for a `:user` resource, the `user_root_path` will be used if it exists, otherwise the default `root_path` will be used. This means that you need to set the root inside your routes:
154
+ After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect to. For instance, when using a `:user` resource, the `user_root_path` will be used if it exists; otherwise, the default `root_path` will be used. This means that you need to set the root inside your routes:
150
155
 
151
156
  ```ruby
152
157
  root to: "home#index"
@@ -157,7 +162,7 @@ You can also override `after_sign_in_path_for` and `after_sign_out_path_for` to
157
162
  Notice that if your Devise model is called `Member` instead of `User`, for example, then the helpers available are:
158
163
 
159
164
  ```ruby
160
- before_filter :authenticate_member!
165
+ before_action :authenticate_member!
161
166
 
162
167
  member_signed_in?
163
168
 
@@ -168,65 +173,74 @@ member_session
168
173
 
169
174
  ### Configuring Models
170
175
 
171
- The Devise method in your models also accepts some options to configure its modules. For example, you can choose the cost of the encryption algorithm with:
176
+ The Devise method in your models also accepts some options to configure its modules. For example, you can choose the cost of the hashing algorithm with:
172
177
 
173
178
  ```ruby
174
179
  devise :database_authenticatable, :registerable, :confirmable, :recoverable, stretches: 20
175
180
  ```
176
181
 
177
- Besides `:stretches`, you can define `:pepper`, `:encryptor`, `:confirm_within`, `:remember_for`, `:timeout_in`, `:unlock_in` among other options. For more details, see the initializer file that was created when you invoked the "devise:install" generator described above.
182
+ Besides `:stretches`, you can define `:pepper`, `:encryptor`, `:confirm_within`, `:remember_for`, `:timeout_in`, `:unlock_in` among other options. For more details, see the initializer file that was created when you invoked the "devise:install" generator described above. This file is usually located at `/config/initializers/devise.rb`.
178
183
 
179
184
  ### Strong Parameters
180
185
 
186
+ ![The Parameter Sanitizer API has changed for Devise 4](http://messages.hellobits.com/warning.svg?message=The%20Parameter%20Sanitizer%20API%20has%20changed%20for%20Devise%204)
187
+
188
+ *For previous Devise versions see https://github.com/plataformatec/devise/tree/3-stable#strong-parameters*
189
+
181
190
  When you customize your own views, you may end up adding new attributes to forms. Rails 4 moved the parameter sanitization from the model to the controller, causing Devise to handle this concern at the controller as well.
182
191
 
183
- There are just three actions in Devise that allows any set of parameters to be passed down to the model, therefore requiring sanitization. Their names and the permitted parameters by default are:
192
+ There are just three actions in Devise that allow any set of parameters to be passed down to the model, therefore requiring sanitization. Their names and default permitted parameters are:
184
193
 
185
- * `sign_in` (`Devise::SessionsController#new`) - Permits only the authentication keys (like `email`)
194
+ * `sign_in` (`Devise::SessionsController#create`) - Permits only the authentication keys (like `email`)
186
195
  * `sign_up` (`Devise::RegistrationsController#create`) - Permits authentication keys plus `password` and `password_confirmation`
187
196
  * `account_update` (`Devise::RegistrationsController#update`) - Permits authentication keys plus `password`, `password_confirmation` and `current_password`
188
197
 
189
- In case you want to permit additional parameters (the lazy way™) you can do with a simple before filter in your `ApplicationController`:
198
+ In case you want to permit additional parameters (the lazy way™), you can do so using a simple before filter in your `ApplicationController`:
190
199
 
191
200
  ```ruby
192
201
  class ApplicationController < ActionController::Base
193
- before_filter :configure_permitted_parameters, if: :devise_controller?
202
+ before_action :configure_permitted_parameters, if: :devise_controller?
194
203
 
195
204
  protected
196
205
 
197
206
  def configure_permitted_parameters
198
- devise_parameter_sanitizer.for(:sign_up) << :username
207
+ devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
199
208
  end
200
209
  end
201
210
  ```
202
211
 
203
- The above works for any additional fields where the parameters are simple scalar types. If you have nested attributes (say you're using `accepts_nested_parameters_for`), then you will need to tell devise about those nestings and types. Devise allows you to completely change Devise defaults or invoke custom behaviour by passing a block:
212
+ The above works for any additional fields where the parameters are simple scalar types. If you have nested attributes (say you're using `accepts_nested_attributes_for`), then you will need to tell devise about those nestings and types. Devise allows you to completely change Devise defaults or invoke custom behaviour by passing a block:
204
213
 
205
214
  To permit simple scalar values for username and email, use this
206
215
 
207
216
  ```ruby
208
217
  def configure_permitted_parameters
209
- devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email) }
218
+ devise_parameter_sanitizer.permit(:sign_in) do |user_params|
219
+ user_params.permit(:username, :email)
220
+ end
210
221
  end
211
222
  ```
212
223
 
213
- If you have some checkboxes that express the roles a user may take on registration, the browser will send those selected checkboxes as an array. An array is not one of Strong Parameters permitted scalars, so we need to configure Devise thusly:
224
+ If you have some checkboxes that express the roles a user may take on registration, the browser will send those selected checkboxes as an array. An array is not one of Strong Parameters' permitted scalars, so we need to configure Devise in the following way:
214
225
 
215
226
  ```ruby
216
227
  def configure_permitted_parameters
217
- devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(roles: [], :email, :password, :password_confirmation) }
228
+ devise_parameter_sanitizer.permit(:sign_up) do |user_params|
229
+ user_params.permit({ roles: [] }, :email, :password, :password_confirmation)
230
+ end
218
231
  end
219
232
  ```
220
233
  For the list of permitted scalars, and how to declare permitted keys in nested hashes and arrays, see
221
234
 
222
235
  https://github.com/rails/strong_parameters#nested-parameters
223
236
 
224
- If you have multiple Devise models, you may want to set up different parameter sanitizer per model. In this case, we recommend inheriting from `Devise::ParameterSanitizer` and add your own logic:
237
+ If you have multiple Devise models, you may want to set up a different parameter sanitizer per model. In this case, we recommend inheriting from `Devise::ParameterSanitizer` and adding your own logic:
225
238
 
226
239
  ```ruby
227
240
  class User::ParameterSanitizer < Devise::ParameterSanitizer
228
- def sign_in
229
- default_params.permit(:username, :email)
241
+ def initialize(*)
242
+ super
243
+ permit(:sign_up, keys: [:username, :email])
230
244
  end
231
245
  end
232
246
  ```
@@ -267,7 +281,7 @@ After doing so, you will be able to have views based on the role like `users/ses
267
281
  rails generate devise:views users
268
282
  ```
269
283
 
270
- If you want to generate only a few set of views, like the ones for the `registrable` and `confirmable` module,
284
+ If you would like to generate only a few sets of views, like the ones for the `registerable` and `confirmable` module,
271
285
  you can pass a list of modules to the generator with the `-v` flag.
272
286
 
273
287
  ```console
@@ -278,29 +292,39 @@ rails generate devise:views -v registrations confirmations
278
292
 
279
293
  If the customization at the views level is not enough, you can customize each controller by following these steps:
280
294
 
281
- 1. Create your custom controller, for example a `Admins::SessionsController`:
295
+ 1. Create your custom controllers using the generator which requires a scope:
296
+
297
+ ```console
298
+ rails generate devise:controllers [scope]
299
+ ```
300
+
301
+ If you specify `users` as the scope, controllers will be created in `app/controllers/users/`.
302
+ And the sessions controller will look like this:
282
303
 
283
304
  ```ruby
284
- class Admins::SessionsController < Devise::SessionsController
305
+ class Users::SessionsController < Devise::SessionsController
306
+ # GET /resource/sign_in
307
+ # def new
308
+ # super
309
+ # end
310
+ ...
285
311
  end
286
312
  ```
287
313
 
288
- Note that in the above example, the controller needs to be created in the `app/controller/admins/` directory.
289
-
290
314
  2. Tell the router to use this controller:
291
315
 
292
316
  ```ruby
293
- devise_for :admins, controllers: { sessions: "admins/sessions" }
317
+ devise_for :users, controllers: { sessions: "users/sessions" }
294
318
  ```
295
319
 
296
- 3. Copy the views from `devise/sessions` to `admins/sessions`. Since the controller was changed, it won't use the default views located in `devise/sessions`.
320
+ 3. Copy the views from `devise/sessions` to `users/sessions`. Since the controller was changed, it won't use the default views located in `devise/sessions`.
297
321
 
298
322
  4. Finally, change or extend the desired controller actions.
299
323
 
300
324
  You can completely override a controller action:
301
325
 
302
326
  ```ruby
303
- class Admins::SessionsController < Devise::SessionsController
327
+ class Users::SessionsController < Devise::SessionsController
304
328
  def create
305
329
  # custom sign-in code
306
330
  end
@@ -310,7 +334,7 @@ If the customization at the views level is not enough, you can customize each co
310
334
  Or you can simply add new behaviour to it:
311
335
 
312
336
  ```ruby
313
- class Admins::SessionsController < Devise::SessionsController
337
+ class Users::SessionsController < Devise::SessionsController
314
338
  def create
315
339
  super do |resource|
316
340
  BackgroundWorker.trigger(resource)
@@ -321,7 +345,7 @@ If the customization at the views level is not enough, you can customize each co
321
345
 
322
346
  This is useful for triggering background jobs or logging events during certain actions.
323
347
 
324
- Remember that Devise uses flash messages to let users know if sign in was successful or failed. Devise expects your application to call `flash[:notice]` and `flash[:alert]` as appropriate. Do not print the entire flash hash, print only specific keys. In some circumstances, Devise adds a `:timedout` key to the flash hash, which is not meant for display. Remove this key from the hash if you intend to print the entire hash.
348
+ Remember that Devise uses flash messages to let users know if sign in was successful or unsuccessful. Devise expects your application to call `flash[:notice]` and `flash[:alert]` as appropriate. Do not print the entire flash hash, print only specific keys. In some circumstances, Devise adds a `:timedout` key to the flash hash, which is not meant for display. Remove this key from the hash if you intend to print the entire hash.
325
349
 
326
350
  ### Configuring routes
327
351
 
@@ -331,9 +355,9 @@ Devise also ships with default routes. If you need to customize them, you should
331
355
  devise_for :users, path: "auth", path_names: { sign_in: 'login', sign_out: 'logout', password: 'secret', confirmation: 'verification', unlock: 'unblock', registration: 'register', sign_up: 'cmon_let_me_in' }
332
356
  ```
333
357
 
334
- Be sure to check `devise_for` documentation for details.
358
+ Be sure to check `devise_for` [documentation](http://www.rubydoc.info/github/plataformatec/devise/master/ActionDispatch/Routing/Mapper%3Adevise_for) for details.
335
359
 
336
- If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is to create your routes normally and wrap them in a `devise_scope` block in the router:
360
+ If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is create your routes normally and wrap them in a `devise_scope` block in the router:
337
361
 
338
362
  ```ruby
339
363
  devise_scope :user do
@@ -341,11 +365,11 @@ devise_scope :user do
341
365
  end
342
366
  ```
343
367
 
344
- This way you tell Devise to use the scope `:user` when "/sign_in" is accessed. Notice `devise_scope` is also aliased as `as` in your router.
368
+ This way, you tell Devise to use the scope `:user` when "/sign_in" is accessed. Notice `devise_scope` is also aliased as `as` in your router.
345
369
 
346
370
  ### I18n
347
371
 
348
- Devise uses flash messages with I18n with the flash keys :notice and :alert. To customize your app, you can set up your locale file:
372
+ Devise uses flash messages with I18n, in conjunction with the flash keys :notice and :alert. To customize your app, you can set up your locale file:
349
373
 
350
374
  ```yaml
351
375
  en:
@@ -383,9 +407,11 @@ Take a look at our locale file to check all available messages. You may also be
383
407
 
384
408
  https://github.com/plataformatec/devise/wiki/I18n
385
409
 
410
+ Caution: Devise Controllers inherit from ApplicationController. If your app uses multiple locales, you should be sure to set I18n.locale in ApplicationController.
411
+
386
412
  ### Test helpers
387
413
 
388
- Devise includes some test helpers for functional specs. In order to use them, you need to include Devise in your functional tests by adding the following to the bottom of your `test/test_helper.rb` file:
414
+ Devise includes some test helpers for functional specs. In order to use them, you need to include Devise in your functional tests by adding the following to the bottom of your `test/test_helper.rb` file (make sure you place it out of scope of `ActiveSupport::TestCase` which is the default class inside of `test/test_helper.rb`):
389
415
 
390
416
  ```ruby
391
417
  class ActionController::TestCase
@@ -393,14 +419,17 @@ class ActionController::TestCase
393
419
  end
394
420
  ```
395
421
 
396
- If you're using RSpec, you can put the following inside a file named `spec/support/devise.rb`:
422
+ If you're using RSpec, you can put the following inside a file named `spec/support/devise.rb` or in your `spec/spec_helper.rb` (or `spec/rails_helper.rb` if you are using rspec-rails):
397
423
 
398
424
  ```ruby
399
425
  RSpec.configure do |config|
400
426
  config.include Devise::TestHelpers, type: :controller
427
+ config.include Devise::TestHelpers, type: :view
401
428
  end
402
429
  ```
403
430
 
431
+ Just be sure that this inclusion is made *after* the `require 'rspec/rails'` directive.
432
+
404
433
  Now you are ready to use the `sign_in` and `sign_out` methods. Such methods have the same signature as in controllers:
405
434
 
406
435
  ```ruby
@@ -411,26 +440,30 @@ sign_out :user # sign_out(scope)
411
440
  sign_out @user # sign_out(resource)
412
441
  ```
413
442
 
414
- There are two things that is important to keep in mind:
443
+ There are two things that are important to keep in mind:
415
444
 
416
- 1. These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session;
445
+ 1. These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. It is undesirable even to include `Devise::TestHelpers` during integration tests. Instead, fill in the form or explicitly set the user in session;
417
446
 
418
- 2. If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
447
+ 2. If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from the router, but since functional tests do not pass through the router, it needs to be stated explicitly. For example, if you are testing the user scope, simply use:
419
448
 
420
449
  ```ruby
421
450
  @request.env["devise.mapping"] = Devise.mappings[:user]
422
451
  get :new
423
452
  ```
424
453
 
425
- ### Omniauth
454
+ You can read more about testing your Rails 3 - Rails 4 controllers with RSpec in the wiki:
455
+
456
+ * https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-%28and-RSpec%29
426
457
 
427
- Devise comes with Omniauth support out of the box to authenticate with other providers. To use it, just specify your omniauth configuration in `config/initializers/devise.rb`:
458
+ ### OmniAuth
459
+
460
+ Devise comes with OmniAuth support out of the box to authenticate with other providers. To use it, simply specify your OmniAuth configuration in `config/initializers/devise.rb`:
428
461
 
429
462
  ```ruby
430
463
  config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
431
464
  ```
432
465
 
433
- You can read more about Omniauth support in the wiki:
466
+ You can read more about OmniAuth support in the wiki:
434
467
 
435
468
  * https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
436
469
 
@@ -443,7 +476,7 @@ Devise allows you to set up as many Devise models as you want. If you want to ha
443
476
  create_table :admins do |t|
444
477
  t.string :email
445
478
  t.string :encrypted_password
446
- t.timestamps
479
+ t.timestamps null: false
447
480
  end
448
481
 
449
482
  # Inside your Admin model
@@ -453,7 +486,7 @@ devise :database_authenticatable, :timeoutable
453
486
  devise_for :admins
454
487
 
455
488
  # Inside your protected controller
456
- before_filter :authenticate_admin!
489
+ before_action :authenticate_admin!
457
490
 
458
491
  # Inside your controllers and views
459
492
  admin_signed_in?
@@ -463,17 +496,43 @@ admin_session
463
496
 
464
497
  Alternatively, you can simply run the Devise generator.
465
498
 
466
- Keep in mind that those models will have completely different routes. They **do not** and **cannot** share the same controller for sign in, sign out and so on. In case you want to have different roles sharing the same actions, we recommend you to use a role-based approach, by either providing a role column or using [CanCan](https://github.com/ryanb/cancan).
499
+ Keep in mind that those models will have completely different routes. They **do not** and **cannot** share the same controller for sign in, sign out and so on. In case you want to have different roles sharing the same actions, we recommend that you use a role-based approach, by either providing a role column or using a dedicated gem for authorization.
500
+
501
+ ### ActiveJob Integration
502
+
503
+ If you are using Rails 4.2 and ActiveJob to deliver ActionMailer messages in the
504
+ background through a queuing back-end, you can send Devise emails through your
505
+ existing queue by overriding the `send_devise_notification` method in your model.
506
+
507
+ ```ruby
508
+ def send_devise_notification(notification, *args)
509
+ devise_mailer.send(notification, self, *args).deliver_later
510
+ end
511
+ ```
512
+
513
+ ### Password reset tokens and Rails logs
514
+
515
+ If you enable the [Recoverable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Recoverable) module, note that a stolen password reset token could give an attacker access to your application. Devise takes effort to generate random, secure tokens, and stores only token digests in the database, never plaintext. However the default logging behavior in Rails can cause plaintext tokens to leak into log files:
516
+
517
+ 1. Action Mailer logs the entire contents of all outgoing emails to the DEBUG level. Password reset tokens delivered to users in email will be leaked.
518
+ 2. Active Job logs all arguments to every enqueued job at the INFO level. If you configure Devise to use `deliver_later` to send password reset emails, password reset tokens will be leaked.
519
+
520
+ Rails sets the production logger level to DEBUG by default. Consider changing your production logger level to WARN if you wish to prevent tokens from being leaked into your logs. In `config/environments/production.rb`:
521
+
522
+ ```ruby
523
+ config.log_level = :warn
524
+ ```
525
+
467
526
 
468
527
  ### Other ORMs
469
528
 
470
- Devise supports ActiveRecord (default) and Mongoid. To choose other ORM, you just need to require it in the initializer file.
529
+ Devise supports ActiveRecord (default) and Mongoid. To select another ORM, simply require it in the initializer file.
471
530
 
472
531
  ## Additional information
473
532
 
474
533
  ### Heroku
475
534
 
476
- Using Devise on Heroku with Ruby on Rails 3.1 requires setting:
535
+ Using Devise on Heroku with Ruby on Rails 3.2 requires setting:
477
536
 
478
537
  ```ruby
479
538
  config.assets.initialize_on_precompile = false
@@ -495,6 +554,6 @@ https://github.com/plataformatec/devise/graphs/contributors
495
554
 
496
555
  ## License
497
556
 
498
- MIT License. Copyright 2009-2014 Plataformatec. http://plataformatec.com.br
557
+ MIT License. Copyright 2009-2016 Plataformatec. http://plataformatec.com.br
499
558
 
500
- You are not granted rights or licenses to the trademarks of the Plataformatec, including without limitation the Devise name or logo.
559
+ You are not granted rights or licenses to the trademarks of Plataformatec, including without limitation the Devise name or logo.
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
- require "bundler/gem_tasks"
2
+
3
+ require 'bundler/gem_tasks'
3
4
  require 'rake/testtask'
4
5
  require 'rdoc/task'
5
6
 
@@ -22,7 +22,7 @@ class Devise::ConfirmationsController < DeviseController
22
22
  yield resource if block_given?
23
23
 
24
24
  if resource.errors.empty?
25
- set_flash_message(:notice, :confirmed) if is_flashing_format?
25
+ set_flash_message!(:notice, :confirmed)
26
26
  respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
27
27
  else
28
28
  respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
@@ -33,15 +33,19 @@ class Devise::ConfirmationsController < DeviseController
33
33
 
34
34
  # The path used after resending confirmation instructions.
35
35
  def after_resending_confirmation_instructions_path_for(resource_name)
36
- new_session_path(resource_name) if is_navigational_format?
36
+ is_navigational_format? ? new_session_path(resource_name) : '/'
37
37
  end
38
38
 
39
39
  # The path used after confirmation.
40
40
  def after_confirmation_path_for(resource_name, resource)
41
- if signed_in?
41
+ if signed_in?(resource_name)
42
42
  signed_in_root_path(resource)
43
43
  else
44
44
  new_session_path(resource_name)
45
45
  end
46
46
  end
47
+
48
+ def translation_scope
49
+ 'devise.confirmations'
50
+ end
47
51
  end
@@ -1,5 +1,5 @@
1
1
  class Devise::OmniauthCallbacksController < DeviseController
2
- prepend_before_filter { request.env["devise.skip_timeout"] = true }
2
+ prepend_before_action { request.env["devise.skip_timeout"] = true }
3
3
 
4
4
  def passthru
5
5
  render status: 404, text: "Not found. Authentication passthru."
@@ -13,18 +13,22 @@ class Devise::OmniauthCallbacksController < DeviseController
13
13
  protected
14
14
 
15
15
  def failed_strategy
16
- env["omniauth.error.strategy"]
16
+ request.respond_to?(:get_header) ? request.get_header("omniauth.error.strategy") : env["omniauth.error.strategy"]
17
17
  end
18
18
 
19
19
  def failure_message
20
- exception = env["omniauth.error"]
20
+ exception = request.respond_to?(:get_header) ? request.get_header("omniauth.error") : env["omniauth.error"]
21
21
  error = exception.error_reason if exception.respond_to?(:error_reason)
22
22
  error ||= exception.error if exception.respond_to?(:error)
23
- error ||= env["omniauth.error.type"].to_s
23
+ error ||= (request.respond_to?(:get_header) ? request.get_header("omniauth.error.type") : env["omniauth.error.type"]).to_s
24
24
  error.to_s.humanize if error
25
25
  end
26
26
 
27
27
  def after_omniauth_failure_path_for(scope)
28
28
  new_session_path(scope)
29
29
  end
30
+
31
+ def translation_scope
32
+ 'devise.omniauth_callbacks'
33
+ end
30
34
  end
@@ -1,7 +1,7 @@
1
1
  class Devise::PasswordsController < DeviseController
2
- prepend_before_filter :require_no_authentication
2
+ prepend_before_action :require_no_authentication
3
3
  # Render the #edit only if coming from a reset password email link
4
- append_before_filter :assert_reset_token_passed, only: :edit
4
+ append_before_action :assert_reset_token_passed, only: :edit
5
5
 
6
6
  # GET /resource/password/new
7
7
  def new
@@ -23,6 +23,7 @@ class Devise::PasswordsController < DeviseController
23
23
  # GET /resource/password/edit?reset_password_token=abcdef
24
24
  def edit
25
25
  self.resource = resource_class.new
26
+ set_minimum_password_length
26
27
  resource.reset_password_token = params[:reset_password_token]
27
28
  end
28
29
 
@@ -33,18 +34,23 @@ class Devise::PasswordsController < DeviseController
33
34
 
34
35
  if resource.errors.empty?
35
36
  resource.unlock_access! if unlockable?(resource)
36
- flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
37
- set_flash_message(:notice, flash_message) if is_flashing_format?
38
- sign_in(resource_name, resource)
37
+ if Devise.sign_in_after_reset_password
38
+ flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
39
+ set_flash_message!(:notice, flash_message)
40
+ sign_in(resource_name, resource)
41
+ else
42
+ set_flash_message!(:notice, :updated_not_active)
43
+ end
39
44
  respond_with resource, location: after_resetting_password_path_for(resource)
40
45
  else
46
+ set_minimum_password_length
41
47
  respond_with resource
42
48
  end
43
49
  end
44
50
 
45
51
  protected
46
52
  def after_resetting_password_path_for(resource)
47
- after_sign_in_path_for(resource)
53
+ Devise.sign_in_after_reset_password ? after_sign_in_path_for(resource) : new_session_path(resource_name)
48
54
  end
49
55
 
50
56
  # The path used after sending reset password instructions
@@ -67,4 +73,8 @@ class Devise::PasswordsController < DeviseController
67
73
  resource.respond_to?(:unlock_strategy_enabled?) &&
68
74
  resource.unlock_strategy_enabled?(:email)
69
75
  end
76
+
77
+ def translation_scope
78
+ 'devise.passwords'
79
+ end
70
80
  end