devise 3.5.10 → 4.6.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 (257) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +240 -1147
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +240 -65
  5. data/app/controllers/devise/confirmations_controller.rb +3 -1
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -6
  7. data/app/controllers/devise/passwords_controller.rb +7 -4
  8. data/app/controllers/devise/registrations_controller.rb +39 -18
  9. data/app/controllers/devise/sessions_controller.rb +9 -7
  10. data/app/controllers/devise/unlocks_controller.rb +4 -2
  11. data/app/controllers/devise_controller.rb +23 -10
  12. data/app/helpers/devise_helper.rb +12 -19
  13. data/app/mailers/devise/mailer.rb +6 -0
  14. data/app/views/devise/confirmations/new.html.erb +2 -2
  15. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  16. data/app/views/devise/passwords/edit.html.erb +2 -2
  17. data/app/views/devise/passwords/new.html.erb +2 -2
  18. data/app/views/devise/registrations/edit.html.erb +9 -5
  19. data/app/views/devise/registrations/new.html.erb +4 -4
  20. data/app/views/devise/sessions/new.html.erb +4 -4
  21. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  22. data/app/views/devise/shared/_links.html.erb +7 -7
  23. data/app/views/devise/unlocks/new.html.erb +2 -2
  24. data/config/locales/en.yml +3 -0
  25. data/lib/devise/controllers/helpers.rb +23 -20
  26. data/lib/devise/controllers/rememberable.rb +3 -1
  27. data/lib/devise/controllers/scoped_views.rb +2 -0
  28. data/lib/devise/controllers/sign_in_out.rb +34 -11
  29. data/lib/devise/controllers/store_location.rb +25 -7
  30. data/lib/devise/controllers/url_helpers.rb +2 -0
  31. data/lib/devise/delegator.rb +2 -0
  32. data/lib/devise/encryptor.rb +6 -4
  33. data/lib/devise/failure_app.rb +81 -37
  34. data/lib/devise/hooks/activatable.rb +2 -0
  35. data/lib/devise/hooks/csrf_cleaner.rb +2 -0
  36. data/lib/devise/hooks/forgetable.rb +2 -0
  37. data/lib/devise/hooks/lockable.rb +6 -1
  38. data/lib/devise/hooks/proxy.rb +3 -1
  39. data/lib/devise/hooks/rememberable.rb +2 -0
  40. data/lib/devise/hooks/timeoutable.rb +2 -0
  41. data/lib/devise/hooks/trackable.rb +2 -0
  42. data/lib/devise/mailers/helpers.rb +7 -4
  43. data/lib/devise/mapping.rb +2 -0
  44. data/lib/devise/models/authenticatable.rb +51 -25
  45. data/lib/devise/models/confirmable.rb +76 -27
  46. data/lib/devise/models/database_authenticatable.rb +91 -23
  47. data/lib/devise/models/lockable.rb +10 -4
  48. data/lib/devise/models/omniauthable.rb +2 -0
  49. data/lib/devise/models/recoverable.rb +31 -19
  50. data/lib/devise/models/registerable.rb +4 -0
  51. data/lib/devise/models/rememberable.rb +5 -10
  52. data/lib/devise/models/timeoutable.rb +2 -0
  53. data/lib/devise/models/trackable.rb +15 -1
  54. data/lib/devise/models/validatable.rb +10 -3
  55. data/lib/devise/models.rb +3 -1
  56. data/lib/devise/modules.rb +2 -0
  57. data/lib/devise/omniauth/config.rb +2 -0
  58. data/lib/devise/omniauth/url_helpers.rb +14 -5
  59. data/lib/devise/omniauth.rb +2 -0
  60. data/lib/devise/orm/active_record.rb +5 -1
  61. data/lib/devise/orm/mongoid.rb +6 -2
  62. data/lib/devise/parameter_filter.rb +4 -0
  63. data/lib/devise/parameter_sanitizer.rb +139 -65
  64. data/lib/devise/rails/routes.rb +42 -31
  65. data/lib/devise/rails/warden_compat.rb +3 -10
  66. data/lib/devise/rails.rb +7 -16
  67. data/lib/devise/secret_key_finder.rb +27 -0
  68. data/lib/devise/strategies/authenticatable.rb +2 -0
  69. data/lib/devise/strategies/base.rb +2 -0
  70. data/lib/devise/strategies/database_authenticatable.rb +11 -4
  71. data/lib/devise/strategies/rememberable.rb +2 -0
  72. data/lib/devise/test/controller_helpers.rb +165 -0
  73. data/lib/devise/test/integration_helpers.rb +63 -0
  74. data/lib/devise/test_helpers.rb +7 -124
  75. data/lib/devise/time_inflector.rb +2 -0
  76. data/lib/devise/token_generator.rb +3 -41
  77. data/lib/devise/version.rb +3 -1
  78. data/lib/devise.rb +61 -40
  79. data/lib/generators/active_record/devise_generator.rb +29 -10
  80. data/lib/generators/active_record/templates/migration.rb +4 -2
  81. data/lib/generators/active_record/templates/migration_existing.rb +4 -2
  82. data/lib/generators/devise/controllers_generator.rb +3 -1
  83. data/lib/generators/devise/devise_generator.rb +4 -2
  84. data/lib/generators/devise/install_generator.rb +17 -0
  85. data/lib/generators/devise/orm_helpers.rb +10 -21
  86. data/lib/generators/devise/views_generator.rb +7 -8
  87. data/lib/generators/mongoid/devise_generator.rb +7 -5
  88. data/lib/generators/templates/README +1 -8
  89. data/lib/generators/templates/controllers/confirmations_controller.rb +2 -0
  90. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +2 -0
  91. data/lib/generators/templates/controllers/passwords_controller.rb +2 -0
  92. data/lib/generators/templates/controllers/registrations_controller.rb +6 -4
  93. data/lib/generators/templates/controllers/sessions_controller.rb +4 -2
  94. data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
  95. data/lib/generators/templates/devise.rb +50 -20
  96. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  97. data/lib/generators/templates/markerb/password_change.markerb +2 -2
  98. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +5 -1
  99. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +6 -1
  100. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +4 -1
  101. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -3
  102. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +11 -3
  103. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +7 -2
  104. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +4 -1
  105. metadata +15 -307
  106. data/.gitignore +0 -10
  107. data/.travis.yml +0 -44
  108. data/.yardopts +0 -9
  109. data/CODE_OF_CONDUCT.md +0 -22
  110. data/CONTRIBUTING.md +0 -16
  111. data/Gemfile +0 -30
  112. data/Gemfile.lock +0 -187
  113. data/Rakefile +0 -36
  114. data/devise.gemspec +0 -27
  115. data/devise.png +0 -0
  116. data/gemfiles/Gemfile.rails-3.2-stable +0 -29
  117. data/gemfiles/Gemfile.rails-3.2-stable.lock +0 -172
  118. data/gemfiles/Gemfile.rails-4.0-stable +0 -30
  119. data/gemfiles/Gemfile.rails-4.0-stable.lock +0 -166
  120. data/gemfiles/Gemfile.rails-4.1-stable +0 -30
  121. data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -171
  122. data/gemfiles/Gemfile.rails-4.2-stable +0 -30
  123. data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -193
  124. data/script/cached-bundle +0 -49
  125. data/script/s3-put +0 -71
  126. data/test/controllers/custom_registrations_controller_test.rb +0 -40
  127. data/test/controllers/custom_strategy_test.rb +0 -62
  128. data/test/controllers/helper_methods_test.rb +0 -21
  129. data/test/controllers/helpers_test.rb +0 -316
  130. data/test/controllers/inherited_controller_i18n_messages_test.rb +0 -51
  131. data/test/controllers/internal_helpers_test.rb +0 -129
  132. data/test/controllers/load_hooks_controller_test.rb +0 -19
  133. data/test/controllers/passwords_controller_test.rb +0 -31
  134. data/test/controllers/sessions_controller_test.rb +0 -103
  135. data/test/controllers/url_helpers_test.rb +0 -65
  136. data/test/delegator_test.rb +0 -19
  137. data/test/devise_test.rb +0 -107
  138. data/test/failure_app_test.rb +0 -315
  139. data/test/generators/active_record_generator_test.rb +0 -109
  140. data/test/generators/controllers_generator_test.rb +0 -48
  141. data/test/generators/devise_generator_test.rb +0 -39
  142. data/test/generators/install_generator_test.rb +0 -13
  143. data/test/generators/mongoid_generator_test.rb +0 -23
  144. data/test/generators/views_generator_test.rb +0 -103
  145. data/test/helpers/devise_helper_test.rb +0 -49
  146. data/test/integration/authenticatable_test.rb +0 -729
  147. data/test/integration/confirmable_test.rb +0 -324
  148. data/test/integration/database_authenticatable_test.rb +0 -95
  149. data/test/integration/http_authenticatable_test.rb +0 -105
  150. data/test/integration/lockable_test.rb +0 -239
  151. data/test/integration/omniauthable_test.rb +0 -135
  152. data/test/integration/recoverable_test.rb +0 -347
  153. data/test/integration/registerable_test.rb +0 -359
  154. data/test/integration/rememberable_test.rb +0 -214
  155. data/test/integration/timeoutable_test.rb +0 -184
  156. data/test/integration/trackable_test.rb +0 -92
  157. data/test/mailers/confirmation_instructions_test.rb +0 -115
  158. data/test/mailers/reset_password_instructions_test.rb +0 -96
  159. data/test/mailers/unlock_instructions_test.rb +0 -91
  160. data/test/mapping_test.rb +0 -134
  161. data/test/models/authenticatable_test.rb +0 -23
  162. data/test/models/confirmable_test.rb +0 -511
  163. data/test/models/database_authenticatable_test.rb +0 -269
  164. data/test/models/lockable_test.rb +0 -350
  165. data/test/models/omniauthable_test.rb +0 -7
  166. data/test/models/recoverable_test.rb +0 -251
  167. data/test/models/registerable_test.rb +0 -7
  168. data/test/models/rememberable_test.rb +0 -169
  169. data/test/models/serializable_test.rb +0 -49
  170. data/test/models/timeoutable_test.rb +0 -51
  171. data/test/models/trackable_test.rb +0 -41
  172. data/test/models/validatable_test.rb +0 -127
  173. data/test/models_test.rb +0 -153
  174. data/test/omniauth/config_test.rb +0 -57
  175. data/test/omniauth/url_helpers_test.rb +0 -54
  176. data/test/orm/active_record.rb +0 -10
  177. data/test/orm/mongoid.rb +0 -13
  178. data/test/parameter_sanitizer_test.rb +0 -81
  179. data/test/rails_app/Rakefile +0 -6
  180. data/test/rails_app/app/active_record/admin.rb +0 -6
  181. data/test/rails_app/app/active_record/shim.rb +0 -2
  182. data/test/rails_app/app/active_record/user.rb +0 -6
  183. data/test/rails_app/app/active_record/user_on_engine.rb +0 -7
  184. data/test/rails_app/app/active_record/user_on_main_app.rb +0 -7
  185. data/test/rails_app/app/active_record/user_without_email.rb +0 -8
  186. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  187. data/test/rails_app/app/controllers/admins_controller.rb +0 -6
  188. data/test/rails_app/app/controllers/application_controller.rb +0 -12
  189. data/test/rails_app/app/controllers/application_with_fake_engine.rb +0 -30
  190. data/test/rails_app/app/controllers/custom/registrations_controller.rb +0 -31
  191. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  192. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  193. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  194. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  195. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  196. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  197. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +0 -3
  198. data/test/rails_app/app/mailers/users/mailer.rb +0 -3
  199. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +0 -4
  200. data/test/rails_app/app/mongoid/admin.rb +0 -29
  201. data/test/rails_app/app/mongoid/shim.rb +0 -23
  202. data/test/rails_app/app/mongoid/user.rb +0 -39
  203. data/test/rails_app/app/mongoid/user_on_engine.rb +0 -39
  204. data/test/rails_app/app/mongoid/user_on_main_app.rb +0 -39
  205. data/test/rails_app/app/mongoid/user_without_email.rb +0 -33
  206. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  207. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  208. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  209. data/test/rails_app/app/views/home/index.html.erb +0 -1
  210. data/test/rails_app/app/views/home/join.html.erb +0 -1
  211. data/test/rails_app/app/views/home/private.html.erb +0 -1
  212. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  213. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  214. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  215. data/test/rails_app/app/views/users/index.html.erb +0 -1
  216. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  217. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  218. data/test/rails_app/bin/bundle +0 -3
  219. data/test/rails_app/bin/rails +0 -4
  220. data/test/rails_app/bin/rake +0 -4
  221. data/test/rails_app/config/application.rb +0 -40
  222. data/test/rails_app/config/boot.rb +0 -14
  223. data/test/rails_app/config/database.yml +0 -18
  224. data/test/rails_app/config/environment.rb +0 -5
  225. data/test/rails_app/config/environments/development.rb +0 -30
  226. data/test/rails_app/config/environments/production.rb +0 -84
  227. data/test/rails_app/config/environments/test.rb +0 -41
  228. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  229. data/test/rails_app/config/initializers/devise.rb +0 -180
  230. data/test/rails_app/config/initializers/inflections.rb +0 -2
  231. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  232. data/test/rails_app/config/initializers/session_store.rb +0 -1
  233. data/test/rails_app/config/routes.rb +0 -125
  234. data/test/rails_app/config.ru +0 -4
  235. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
  236. data/test/rails_app/db/schema.rb +0 -55
  237. data/test/rails_app/lib/shared_admin.rb +0 -17
  238. data/test/rails_app/lib/shared_user.rb +0 -29
  239. data/test/rails_app/lib/shared_user_without_email.rb +0 -26
  240. data/test/rails_app/lib/shared_user_without_omniauth.rb +0 -13
  241. data/test/rails_app/public/404.html +0 -26
  242. data/test/rails_app/public/422.html +0 -26
  243. data/test/rails_app/public/500.html +0 -26
  244. data/test/rails_app/public/favicon.ico +0 -0
  245. data/test/rails_test.rb +0 -9
  246. data/test/routes_test.rb +0 -264
  247. data/test/support/action_controller/record_identifier.rb +0 -10
  248. data/test/support/assertions.rb +0 -39
  249. data/test/support/helpers.rb +0 -77
  250. data/test/support/integration.rb +0 -92
  251. data/test/support/locale/en.yml +0 -8
  252. data/test/support/mongoid.yml +0 -6
  253. data/test/support/webrat/integrations/rails.rb +0 -24
  254. data/test/test_helper.rb +0 -34
  255. data/test/test_helpers_test.rb +0 -178
  256. data/test/test_models.rb +0 -33
  257. data/test/time_helpers.rb +0 -137
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devise
4
+ module Test
5
+ # `Devise::Test::ControllerHelpers` provides a facility to test controllers
6
+ # in isolation when using `ActionController::TestCase` allowing you to
7
+ # quickly sign_in or sign_out a user. Do not use
8
+ # `Devise::Test::ControllerHelpers` in integration tests.
9
+ #
10
+ # Examples
11
+ #
12
+ # class PostsTest < ActionController::TestCase
13
+ # include Devise::Test::ControllerHelpers
14
+ #
15
+ # test 'authenticated users can GET index' do
16
+ # sign_in users(:bob)
17
+ #
18
+ # get :index
19
+ # assert_response :success
20
+ # end
21
+ # end
22
+ #
23
+ # Important: you should not test Warden specific behavior (like callbacks)
24
+ # using `Devise::Test::ControllerHelpers` since it is a stub of the actual
25
+ # behavior. Such callbacks should be tested in your integration suite instead.
26
+ module ControllerHelpers
27
+ extend ActiveSupport::Concern
28
+
29
+ included do
30
+ setup :setup_controller_for_warden, :warden
31
+ end
32
+
33
+ # Override process to consider warden.
34
+ def process(*)
35
+ _catch_warden { super }
36
+
37
+ @response
38
+ end
39
+
40
+ # We need to set up the environment variables and the response in the controller.
41
+ def setup_controller_for_warden #:nodoc:
42
+ @request.env['action_controller.instance'] = @controller
43
+ end
44
+
45
+ # Quick access to Warden::Proxy.
46
+ def warden #:nodoc:
47
+ @request.env['warden'] ||= begin
48
+ manager = Warden::Manager.new(nil) do |config|
49
+ config.merge! Devise.warden_config
50
+ end
51
+ Warden::Proxy.new(@request.env, manager)
52
+ end
53
+ end
54
+
55
+ # sign_in a given resource by storing its keys in the session.
56
+ # This method bypass any warden authentication callback.
57
+ #
58
+ # * +resource+ - The resource that should be authenticated
59
+ # * +scope+ - An optional +Symbol+ with the scope where the resource
60
+ # should be signed in with.
61
+ # Examples:
62
+ #
63
+ # sign_in users(:alice)
64
+ # sign_in users(:alice), scope: :admin
65
+ def sign_in(resource, deprecated = nil, scope: nil)
66
+ if deprecated.present?
67
+ scope = resource
68
+ resource = deprecated
69
+
70
+ ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
71
+ [Devise] sign_in(:#{scope}, resource) on controller tests is deprecated and will be removed from Devise.
72
+ Please use sign_in(resource, scope: :#{scope}) instead.
73
+ DEPRECATION
74
+ end
75
+
76
+ scope ||= Devise::Mapping.find_scope!(resource)
77
+
78
+ warden.instance_variable_get(:@users).delete(scope)
79
+ warden.session_serializer.store(resource, scope)
80
+ end
81
+
82
+ # Sign out a given resource or scope by calling logout on Warden.
83
+ # This method bypass any warden logout callback.
84
+ #
85
+ # Examples:
86
+ #
87
+ # sign_out :user # sign_out(scope)
88
+ # sign_out @user # sign_out(resource)
89
+ #
90
+ def sign_out(resource_or_scope)
91
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
92
+ @controller.instance_variable_set(:"@current_#{scope}", nil)
93
+ user = warden.instance_variable_get(:@users).delete(scope)
94
+ warden.session_serializer.delete(scope, user)
95
+ end
96
+
97
+ protected
98
+
99
+ # Catch warden continuations and handle like the middleware would.
100
+ # Returns nil when interrupted, otherwise the normal result of the block.
101
+ def _catch_warden(&block)
102
+ result = catch(:warden, &block)
103
+
104
+ env = @controller.request.env
105
+
106
+ result ||= {}
107
+
108
+ # Set the response. In production, the rack result is returned
109
+ # from Warden::Manager#call, which the following is modelled on.
110
+ case result
111
+ when Array
112
+ if result.first == 401 && intercept_401?(env) # does this happen during testing?
113
+ _process_unauthenticated(env)
114
+ else
115
+ result
116
+ end
117
+ when Hash
118
+ _process_unauthenticated(env, result)
119
+ else
120
+ result
121
+ end
122
+ end
123
+
124
+ def _process_unauthenticated(env, options = {})
125
+ options[:action] ||= :unauthenticated
126
+ proxy = request.env['warden']
127
+ result = options[:result] || proxy.result
128
+
129
+ ret = case result
130
+ when :redirect
131
+ body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
132
+ [proxy.status, proxy.headers, [body]]
133
+ when :custom
134
+ proxy.custom_response
135
+ else
136
+ request.env["PATH_INFO"] = "/#{options[:action]}"
137
+ request.env["warden.options"] = options
138
+ Warden::Manager._run_callbacks(:before_failure, env, options)
139
+
140
+ status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
141
+ @controller.response.headers.merge!(headers)
142
+ @controller.response.content_type = headers["Content-Type"] unless Rails::VERSION::MAJOR >= 5
143
+ @controller.status = status
144
+ @controller.response.body = response.body
145
+ nil # causes process return @response
146
+ end
147
+
148
+ # ensure that the controller response is set up. In production, this is
149
+ # not necessary since warden returns the results to rack. However, at
150
+ # testing time, we want the response to be available to the testing
151
+ # framework to verify what would be returned to rack.
152
+ if ret.is_a?(Array)
153
+ status, headers, body = *ret
154
+ # ensure the controller response is set to our response.
155
+ @controller.response ||= @response
156
+ @response.status = status
157
+ @response.headers.merge!(headers)
158
+ @response.body = body
159
+ end
160
+
161
+ ret
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devise
4
+ # Devise::Test::IntegrationHelpers is a helper module for facilitating
5
+ # authentication on Rails integration tests to bypass the required steps for
6
+ # signin in or signin out a record.
7
+ #
8
+ # Examples
9
+ #
10
+ # class PostsTest < ActionDispatch::IntegrationTest
11
+ # include Devise::Test::IntegrationHelpers
12
+ #
13
+ # test 'authenticated users can see posts' do
14
+ # sign_in users(:bob)
15
+ #
16
+ # get '/posts'
17
+ # assert_response :success
18
+ # end
19
+ # end
20
+ module Test
21
+ module IntegrationHelpers
22
+ def self.included(base)
23
+ base.class_eval do
24
+ include Warden::Test::Helpers
25
+
26
+ setup :setup_integration_for_devise
27
+ teardown :teardown_integration_for_devise
28
+ end
29
+ end
30
+
31
+ # Signs in a specific resource, mimicking a successfull sign in
32
+ # operation through +Devise::SessionsController#create+.
33
+ #
34
+ # * +resource+ - The resource that should be authenticated
35
+ # * +scope+ - An optional +Symbol+ with the scope where the resource
36
+ # should be signed in with.
37
+ def sign_in(resource, scope: nil)
38
+ scope ||= Devise::Mapping.find_scope!(resource)
39
+
40
+ login_as(resource, scope: scope)
41
+ end
42
+
43
+ # Signs out a specific scope from the session.
44
+ #
45
+ # * +resource_or_scope+ - The resource or scope that should be signed out.
46
+ def sign_out(resource_or_scope)
47
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
48
+
49
+ logout scope
50
+ end
51
+
52
+ protected
53
+
54
+ def setup_integration_for_devise
55
+ Warden.test_mode!
56
+ end
57
+
58
+ def teardown_integration_for_devise
59
+ Warden.test_reset!
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,132 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
- # Devise::TestHelpers provides a facility to test controllers in isolation
3
- # when using ActionController::TestCase allowing you to quickly sign_in or
4
- # sign_out a user. Do not use Devise::TestHelpers in integration tests.
5
- #
6
- # Notice you should not test Warden specific behavior (like Warden callbacks)
7
- # using Devise::TestHelpers since it is a stub of the actual behavior. Such
8
- # callbacks should be tested in your integration suite instead.
9
4
  module TestHelpers
10
5
  def self.included(base)
11
6
  base.class_eval do
12
- setup :setup_controller_for_warden, :warden if respond_to?(:setup)
13
- end
14
- end
15
-
16
- # Override process to consider warden.
17
- def process(*)
18
- # Make sure we always return @response, a la ActionController::TestCase::Behaviour#process, even if warden interrupts
19
- _catch_warden { super } || @response
20
- end
21
-
22
- # We need to setup the environment variables and the response in the controller.
23
- def setup_controller_for_warden #:nodoc:
24
- @request.env['action_controller.instance'] = @controller
25
- end
26
-
27
- # Quick access to Warden::Proxy.
28
- def warden #:nodoc:
29
- @request.env['warden'] ||= begin
30
- manager = Warden::Manager.new(nil) do |config|
31
- config.merge! Devise.warden_config
32
- end
33
- Warden::Proxy.new(@request.env, manager)
7
+ ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
8
+ [Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
9
+ For controller tests, please include `Devise::Test::ControllerHelpers` instead.
10
+ DEPRECATION
11
+ include Devise::Test::ControllerHelpers
34
12
  end
35
13
  end
36
-
37
- # sign_in a given resource by storing its keys in the session.
38
- # This method bypass any warden authentication callback.
39
- #
40
- # Examples:
41
- #
42
- # sign_in :user, @user # sign_in(scope, resource)
43
- # sign_in @user # sign_in(resource)
44
- #
45
- def sign_in(resource_or_scope, resource=nil)
46
- scope ||= Devise::Mapping.find_scope!(resource_or_scope)
47
- resource ||= resource_or_scope
48
- warden.instance_variable_get(:@users).delete(scope)
49
- warden.session_serializer.store(resource, scope)
50
- end
51
-
52
- # Sign out a given resource or scope by calling logout on Warden.
53
- # This method bypass any warden logout callback.
54
- #
55
- # Examples:
56
- #
57
- # sign_out :user # sign_out(scope)
58
- # sign_out @user # sign_out(resource)
59
- #
60
- def sign_out(resource_or_scope)
61
- scope = Devise::Mapping.find_scope!(resource_or_scope)
62
- @controller.instance_variable_set(:"@current_#{scope}", nil)
63
- user = warden.instance_variable_get(:@users).delete(scope)
64
- warden.session_serializer.delete(scope, user)
65
- end
66
-
67
- protected
68
-
69
- # Catch warden continuations and handle like the middleware would.
70
- # Returns nil when interrupted, otherwise the normal result of the block.
71
- def _catch_warden(&block)
72
- result = catch(:warden, &block)
73
-
74
- env = @controller.request.env
75
-
76
- result ||= {}
77
-
78
- # Set the response. In production, the rack result is returned
79
- # from Warden::Manager#call, which the following is modelled on.
80
- case result
81
- when Array
82
- if result.first == 401 && intercept_401?(env) # does this happen during testing?
83
- _process_unauthenticated(env)
84
- else
85
- result
86
- end
87
- when Hash
88
- _process_unauthenticated(env, result)
89
- else
90
- result
91
- end
92
- end
93
-
94
- def _process_unauthenticated(env, options = {})
95
- options[:action] ||= :unauthenticated
96
- proxy = env['warden']
97
- result = options[:result] || proxy.result
98
-
99
- ret = case result
100
- when :redirect
101
- body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
102
- [proxy.status, proxy.headers, [body]]
103
- when :custom
104
- proxy.custom_response
105
- else
106
- env["PATH_INFO"] = "/#{options[:action]}"
107
- env["warden.options"] = options
108
- Warden::Manager._run_callbacks(:before_failure, env, options)
109
-
110
- status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
111
- @controller.response.headers.merge!(headers)
112
- @controller.send :render, status: status, text: response.body,
113
- content_type: headers["Content-Type"], location: headers["Location"]
114
- nil # causes process return @response
115
- end
116
-
117
- # ensure that the controller response is set up. In production, this is
118
- # not necessary since warden returns the results to rack. However, at
119
- # testing time, we want the response to be available to the testing
120
- # framework to verify what would be returned to rack.
121
- if ret.is_a?(Array)
122
- # ensure the controller response is set to our response.
123
- @controller.response ||= @response
124
- @response.status = ret.first
125
- @response.headers = ret.second
126
- @response.body = ret.third
127
- end
128
-
129
- ret
130
- end
131
14
  end
132
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/delegation"
2
4
 
3
5
  module Devise
@@ -1,11 +1,10 @@
1
- # Deprecate: Copied verbatim from Rails source, remove once we move to Rails 4 only.
2
- require 'thread_safe'
1
+ # frozen_string_literal: true
2
+
3
3
  require 'openssl'
4
- require 'securerandom'
5
4
 
6
5
  module Devise
7
6
  class TokenGenerator
8
- def initialize(key_generator, digest="SHA256")
7
+ def initialize(key_generator, digest = "SHA256")
9
8
  @key_generator = key_generator
10
9
  @digest = digest
11
10
  end
@@ -30,41 +29,4 @@ module Devise
30
29
  @key_generator.generate_key("Devise #{column}")
31
30
  end
32
31
  end
33
-
34
- # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
35
- # It can be used to derive a number of keys for various purposes from a given secret.
36
- # This lets Rails applications have a single secure secret, but avoid reusing that
37
- # key in multiple incompatible contexts.
38
- class KeyGenerator
39
- def initialize(secret, options = {})
40
- @secret = secret
41
- # The default iterations are higher than required for our key derivation uses
42
- # on the off chance someone uses this for password storage
43
- @iterations = options[:iterations] || 2**16
44
- end
45
-
46
- # Returns a derived key suitable for use. The default key_size is chosen
47
- # to be compatible with the default settings of ActiveSupport::MessageVerifier.
48
- # i.e. OpenSSL::Digest::SHA1#block_length
49
- def generate_key(salt, key_size=64)
50
- OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
51
- end
52
- end
53
-
54
- # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
55
- # re-executing the key generation process when it's called using the same salt and
56
- # key_size
57
- class CachingKeyGenerator
58
- def initialize(key_generator)
59
- @key_generator = key_generator
60
- @cache_keys = ThreadSafe::Cache.new
61
- end
62
-
63
- # Returns a derived key suitable for use. The default key_size is chosen
64
- # to be compatible with the default settings of ActiveSupport::MessageVerifier.
65
- # i.e. OpenSSL::Digest::SHA1#block_length
66
- def generate_key(salt, key_size=64)
67
- @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
68
- end
69
- end
70
32
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
- VERSION = "3.5.10".freeze
4
+ VERSION = "4.6.0".freeze
3
5
  end
data/lib/devise.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
  require 'active_support/core_ext/numeric/time'
3
5
  require 'active_support/dependencies'
@@ -12,19 +14,19 @@ module Devise
12
14
  autoload :FailureApp, 'devise/failure_app'
13
15
  autoload :OmniAuth, 'devise/omniauth'
14
16
  autoload :ParameterFilter, 'devise/parameter_filter'
15
- autoload :BaseSanitizer, 'devise/parameter_sanitizer'
16
17
  autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
17
18
  autoload :TestHelpers, 'devise/test_helpers'
18
19
  autoload :TimeInflector, 'devise/time_inflector'
19
20
  autoload :TokenGenerator, 'devise/token_generator'
21
+ autoload :SecretKeyFinder, 'devise/secret_key_finder'
20
22
 
21
23
  module Controllers
22
- autoload :Helpers, 'devise/controllers/helpers'
23
- autoload :Rememberable, 'devise/controllers/rememberable'
24
- autoload :ScopedViews, 'devise/controllers/scoped_views'
25
- autoload :SignInOut, 'devise/controllers/sign_in_out'
26
- autoload :StoreLocation, 'devise/controllers/store_location'
27
- autoload :UrlHelpers, 'devise/controllers/url_helpers'
24
+ autoload :Helpers, 'devise/controllers/helpers'
25
+ autoload :Rememberable, 'devise/controllers/rememberable'
26
+ autoload :ScopedViews, 'devise/controllers/scoped_views'
27
+ autoload :SignInOut, 'devise/controllers/sign_in_out'
28
+ autoload :StoreLocation, 'devise/controllers/store_location'
29
+ autoload :UrlHelpers, 'devise/controllers/url_helpers'
28
30
  end
29
31
 
30
32
  module Hooks
@@ -36,17 +38,22 @@ module Devise
36
38
  end
37
39
 
38
40
  module Strategies
39
- autoload :Base, 'devise/strategies/base'
41
+ autoload :Base, 'devise/strategies/base'
40
42
  autoload :Authenticatable, 'devise/strategies/authenticatable'
41
43
  end
42
44
 
45
+ module Test
46
+ autoload :ControllerHelpers, 'devise/test/controller_helpers'
47
+ autoload :IntegrationHelpers, 'devise/test/integration_helpers'
48
+ end
49
+
43
50
  # Constants which holds devise configuration for extensions. Those should
44
51
  # not be modified by the "end user" (this is why they are constants).
45
52
  ALL = []
46
- CONTROLLERS = ActiveSupport::OrderedHash.new
47
- ROUTES = ActiveSupport::OrderedHash.new
48
- STRATEGIES = ActiveSupport::OrderedHash.new
49
- URL_HELPERS = ActiveSupport::OrderedHash.new
53
+ CONTROLLERS = {}
54
+ ROUTES = {}
55
+ STRATEGIES = {}
56
+ URL_HELPERS = {}
50
57
 
51
58
  # Strategies that do not require user input.
52
59
  NO_INPUT = []
@@ -62,9 +69,9 @@ module Devise
62
69
  mattr_accessor :rememberable_options
63
70
  @@rememberable_options = {}
64
71
 
65
- # The number of times to encrypt password.
72
+ # The number of times to hash the password.
66
73
  mattr_accessor :stretches
67
- @@stretches = 10
74
+ @@stretches = 11
68
75
 
69
76
  # The default key used when authenticating over http auth.
70
77
  mattr_accessor :http_authentication_key
@@ -84,7 +91,7 @@ module Devise
84
91
 
85
92
  # Keys that should have whitespace stripped.
86
93
  mattr_accessor :strip_whitespace_keys
87
- @@strip_whitespace_keys = []
94
+ @@strip_whitespace_keys = [:email]
88
95
 
89
96
  # If http authentication is enabled by default.
90
97
  mattr_accessor :http_authenticatable
@@ -102,11 +109,11 @@ module Devise
102
109
  mattr_accessor :http_authentication_realm
103
110
  @@http_authentication_realm = "Application"
104
111
 
105
- # Email regex used to validate email formats. It simply asserts that
106
- # an one (and only one) @ exists in the given string. This is mainly
107
- # to give user feedback and not to assert the e-mail validity.
112
+ # Email regex used to validate email formats. It asserts that there are no
113
+ # @ symbols or whitespaces in either the localpart or the domain, and that
114
+ # there is a single @ symbol separating the localpart and the domain.
108
115
  mattr_accessor :email_regexp
109
- @@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/
116
+ @@email_regexp = /\A[^@\s]+@[^@\s]+\z/
110
117
 
111
118
  # Range validation for password length
112
119
  mattr_accessor :password_length
@@ -138,19 +145,22 @@ module Devise
138
145
  @@confirmation_keys = [:email]
139
146
 
140
147
  # Defines if email should be reconfirmable.
141
- # False by default for backwards compatibility.
142
148
  mattr_accessor :reconfirmable
143
- @@reconfirmable = false
149
+ @@reconfirmable = true
144
150
 
145
151
  # Time interval to timeout the user session without activity.
146
152
  mattr_accessor :timeout_in
147
153
  @@timeout_in = 30.minutes
148
154
 
149
- # Used to encrypt password. Please generate one with rake secret.
155
+ # Used to hash the password. Please generate one with rails secret.
150
156
  mattr_accessor :pepper
151
157
  @@pepper = nil
152
158
 
153
- # Used to enable sending notification to user when their password is changed
159
+ # Used to send notification to the original user email when their email is changed.
160
+ mattr_accessor :send_email_changed_notification
161
+ @@send_email_changed_notification = false
162
+
163
+ # Used to enable sending notification to user when their password is changed.
154
164
  mattr_accessor :send_password_change_notification
155
165
  @@send_password_change_notification = false
156
166
 
@@ -203,7 +213,7 @@ module Devise
203
213
 
204
214
  # Skip session storage for the following strategies
205
215
  mattr_accessor :skip_session_storage
206
- @@skip_session_storage = []
216
+ @@skip_session_storage = [:http_auth]
207
217
 
208
218
  # Which formats should be treated as navigational.
209
219
  mattr_accessor :navigational_formats
@@ -215,7 +225,7 @@ module Devise
215
225
 
216
226
  # The default method used while signing out
217
227
  mattr_accessor :sign_out_via
218
- @@sign_out_via = :get
228
+ @@sign_out_via = :delete
219
229
 
220
230
  # The parent controller all Devise controllers inherits from.
221
231
  # Defaults to ApplicationController. This should be set early
@@ -244,15 +254,22 @@ module Devise
244
254
  mattr_accessor :clean_up_csrf_token_on_authentication
245
255
  @@clean_up_csrf_token_on_authentication = true
246
256
 
257
+ # When false, Devise will not attempt to reload routes on eager load.
258
+ # This can reduce the time taken to boot the app but if your application
259
+ # requires the Devise mappings to be loaded during boot time the application
260
+ # won't boot properly.
261
+ mattr_accessor :reload_routes
262
+ @@reload_routes = true
263
+
247
264
  # PRIVATE CONFIGURATION
248
265
 
249
266
  # Store scopes mappings.
250
267
  mattr_reader :mappings
251
- @@mappings = ActiveSupport::OrderedHash.new
268
+ @@mappings = {}
252
269
 
253
270
  # OmniAuth configurations.
254
271
  mattr_reader :omniauth_configs
255
- @@omniauth_configs = ActiveSupport::OrderedHash.new
272
+ @@omniauth_configs = {}
256
273
 
257
274
  # Define a set of modules that are called when a mapping is added.
258
275
  mattr_reader :helpers
@@ -276,14 +293,26 @@ module Devise
276
293
  mattr_accessor :token_generator
277
294
  @@token_generator = nil
278
295
 
279
- # Default way to setup Devise. Run rails generate devise_install to create
296
+ # When set to false, changing a password does not automatically sign in a user
297
+ mattr_accessor :sign_in_after_change_password
298
+ @@sign_in_after_change_password = true
299
+
300
+ def self.rails51? # :nodoc:
301
+ Rails.gem_version >= Gem::Version.new("5.1.x")
302
+ end
303
+
304
+ def self.activerecord51? # :nodoc:
305
+ defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
306
+ end
307
+
308
+ # Default way to set up Devise. Run rails generate devise_install to create
280
309
  # a fresh initializer with all configuration values.
281
310
  def self.setup
282
311
  yield self
283
312
  end
284
313
 
285
314
  class Getter
286
- def initialize name
315
+ def initialize(name)
287
316
  @name = name
288
317
  end
289
318
 
@@ -293,12 +322,8 @@ module Devise
293
322
  end
294
323
 
295
324
  def self.ref(arg)
296
- if defined?(ActiveSupport::Dependencies::ClassCache)
297
- ActiveSupport::Dependencies::reference(arg)
298
- Getter.new(arg)
299
- else
300
- ActiveSupport::Dependencies.ref(arg)
301
- end
325
+ ActiveSupport::Dependencies.reference(arg)
326
+ Getter.new(arg)
302
327
  end
303
328
 
304
329
  def self.available_router_name
@@ -419,7 +444,6 @@ module Devise
419
444
  # config.omniauth :github, APP_ID, APP_SECRET
420
445
  #
421
446
  def self.omniauth(provider, *args)
422
- @@helpers << Devise::OmniAuth::UrlHelpers
423
447
  config = Devise::OmniAuth::Config.new(provider, args)
424
448
  @@omniauth_configs[config.strategy_name.to_sym] = config
425
449
  end
@@ -457,10 +481,7 @@ module Devise
457
481
  mapping.to.serialize_into_session(record)
458
482
  end
459
483
 
460
- warden_config.serialize_from_session(mapping.name) do |key|
461
- # Previous versions contained an additional entry at the beginning of
462
- # key with the record's class name.
463
- args = key[-2, 2]
484
+ warden_config.serialize_from_session(mapping.name) do |args|
464
485
  mapping.to.serialize_from_session(*args)
465
486
  end
466
487
  end