devise 3.5.1 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +281 -1066
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +292 -97
  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 +10 -7
  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 +25 -12
  12. data/app/helpers/devise_helper.rb +23 -18
  13. data/app/mailers/devise/mailer.rb +13 -3
  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/mailer/password_change.html.erb +3 -0
  17. data/app/views/devise/passwords/edit.html.erb +5 -5
  18. data/app/views/devise/passwords/new.html.erb +2 -2
  19. data/app/views/devise/registrations/edit.html.erb +9 -5
  20. data/app/views/devise/registrations/new.html.erb +4 -4
  21. data/app/views/devise/sessions/new.html.erb +4 -4
  22. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  23. data/app/views/devise/shared/_links.html.erb +8 -8
  24. data/app/views/devise/unlocks/new.html.erb +2 -2
  25. data/config/locales/en.yml +7 -2
  26. data/lib/devise/controllers/helpers.rb +42 -33
  27. data/lib/devise/controllers/rememberable.rb +11 -2
  28. data/lib/devise/controllers/scoped_views.rb +2 -0
  29. data/lib/devise/controllers/sign_in_out.rb +40 -21
  30. data/lib/devise/controllers/store_location.rb +25 -7
  31. data/lib/devise/controllers/url_helpers.rb +3 -1
  32. data/lib/devise/delegator.rb +2 -0
  33. data/lib/devise/encryptor.rb +6 -4
  34. data/lib/devise/failure_app.rb +84 -28
  35. data/lib/devise/hooks/activatable.rb +2 -0
  36. data/lib/devise/hooks/csrf_cleaner.rb +2 -0
  37. data/lib/devise/hooks/forgetable.rb +2 -0
  38. data/lib/devise/hooks/lockable.rb +4 -2
  39. data/lib/devise/hooks/proxy.rb +3 -1
  40. data/lib/devise/hooks/rememberable.rb +2 -0
  41. data/lib/devise/hooks/timeoutable.rb +7 -7
  42. data/lib/devise/hooks/trackable.rb +2 -0
  43. data/lib/devise/mailers/helpers.rb +7 -4
  44. data/lib/devise/mapping.rb +3 -1
  45. data/lib/devise/models/authenticatable.rb +63 -33
  46. data/lib/devise/models/confirmable.rb +108 -35
  47. data/lib/devise/models/database_authenticatable.rb +102 -22
  48. data/lib/devise/models/lockable.rb +24 -6
  49. data/lib/devise/models/omniauthable.rb +2 -0
  50. data/lib/devise/models/recoverable.rb +34 -26
  51. data/lib/devise/models/registerable.rb +4 -0
  52. data/lib/devise/models/rememberable.rb +42 -26
  53. data/lib/devise/models/timeoutable.rb +2 -6
  54. data/lib/devise/models/trackable.rb +15 -1
  55. data/lib/devise/models/validatable.rb +10 -3
  56. data/lib/devise/models.rb +3 -1
  57. data/lib/devise/modules.rb +2 -0
  58. data/lib/devise/omniauth/config.rb +2 -0
  59. data/lib/devise/omniauth/url_helpers.rb +14 -5
  60. data/lib/devise/omniauth.rb +4 -5
  61. data/lib/devise/orm/active_record.rb +5 -1
  62. data/lib/devise/orm/mongoid.rb +6 -2
  63. data/lib/devise/parameter_filter.rb +4 -0
  64. data/lib/devise/parameter_sanitizer.rb +139 -65
  65. data/lib/devise/rails/deprecated_constant_accessor.rb +39 -0
  66. data/lib/devise/rails/routes.rb +71 -51
  67. data/lib/devise/rails/warden_compat.rb +3 -10
  68. data/lib/devise/rails.rb +7 -16
  69. data/lib/devise/secret_key_finder.rb +27 -0
  70. data/lib/devise/strategies/authenticatable.rb +5 -3
  71. data/lib/devise/strategies/base.rb +2 -0
  72. data/lib/devise/strategies/database_authenticatable.rb +11 -4
  73. data/lib/devise/strategies/rememberable.rb +5 -6
  74. data/lib/devise/test/controller_helpers.rb +167 -0
  75. data/lib/devise/test/integration_helpers.rb +63 -0
  76. data/lib/devise/test_helpers.rb +7 -124
  77. data/lib/devise/time_inflector.rb +2 -0
  78. data/lib/devise/token_generator.rb +3 -41
  79. data/lib/devise/version.rb +3 -1
  80. data/lib/devise.rb +69 -46
  81. data/lib/generators/active_record/devise_generator.rb +46 -12
  82. data/lib/generators/active_record/templates/migration.rb +4 -2
  83. data/lib/generators/active_record/templates/migration_existing.rb +4 -2
  84. data/lib/generators/devise/controllers_generator.rb +3 -1
  85. data/lib/generators/devise/devise_generator.rb +5 -3
  86. data/lib/generators/devise/install_generator.rb +18 -5
  87. data/lib/generators/devise/orm_helpers.rb +10 -21
  88. data/lib/generators/devise/views_generator.rb +21 -11
  89. data/lib/generators/mongoid/devise_generator.rb +7 -5
  90. data/lib/generators/templates/README +9 -8
  91. data/lib/generators/templates/controllers/README +1 -1
  92. data/lib/generators/templates/controllers/confirmations_controller.rb +2 -0
  93. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +3 -1
  94. data/lib/generators/templates/controllers/passwords_controller.rb +2 -0
  95. data/lib/generators/templates/controllers/registrations_controller.rb +6 -4
  96. data/lib/generators/templates/controllers/sessions_controller.rb +4 -2
  97. data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
  98. data/lib/generators/templates/devise.rb +65 -23
  99. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  100. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  101. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  102. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  103. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  104. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +5 -1
  105. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +10 -2
  106. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +4 -1
  107. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -3
  108. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +11 -3
  109. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +7 -2
  110. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +4 -1
  111. metadata +21 -306
  112. data/.gitignore +0 -10
  113. data/.travis.yml +0 -45
  114. data/.yardopts +0 -9
  115. data/CONTRIBUTING.md +0 -14
  116. data/Gemfile +0 -29
  117. data/Gemfile.lock +0 -191
  118. data/Rakefile +0 -36
  119. data/devise.gemspec +0 -29
  120. data/devise.png +0 -0
  121. data/gemfiles/Gemfile.rails-3.2-stable +0 -29
  122. data/gemfiles/Gemfile.rails-3.2-stable.lock +0 -169
  123. data/gemfiles/Gemfile.rails-4.0-stable +0 -29
  124. data/gemfiles/Gemfile.rails-4.0-stable.lock +0 -163
  125. data/gemfiles/Gemfile.rails-4.1-stable +0 -29
  126. data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -169
  127. data/gemfiles/Gemfile.rails-4.2-stable +0 -29
  128. data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -191
  129. data/script/cached-bundle +0 -49
  130. data/script/s3-put +0 -71
  131. data/test/controllers/custom_registrations_controller_test.rb +0 -40
  132. data/test/controllers/custom_strategy_test.rb +0 -62
  133. data/test/controllers/helpers_test.rb +0 -316
  134. data/test/controllers/inherited_controller_i18n_messages_test.rb +0 -51
  135. data/test/controllers/internal_helpers_test.rb +0 -129
  136. data/test/controllers/load_hooks_controller_test.rb +0 -19
  137. data/test/controllers/passwords_controller_test.rb +0 -31
  138. data/test/controllers/sessions_controller_test.rb +0 -103
  139. data/test/controllers/url_helpers_test.rb +0 -65
  140. data/test/delegator_test.rb +0 -19
  141. data/test/devise_test.rb +0 -107
  142. data/test/failure_app_test.rb +0 -298
  143. data/test/generators/active_record_generator_test.rb +0 -109
  144. data/test/generators/controllers_generator_test.rb +0 -48
  145. data/test/generators/devise_generator_test.rb +0 -39
  146. data/test/generators/install_generator_test.rb +0 -13
  147. data/test/generators/mongoid_generator_test.rb +0 -23
  148. data/test/generators/views_generator_test.rb +0 -96
  149. data/test/helpers/devise_helper_test.rb +0 -49
  150. data/test/integration/authenticatable_test.rb +0 -729
  151. data/test/integration/confirmable_test.rb +0 -324
  152. data/test/integration/database_authenticatable_test.rb +0 -95
  153. data/test/integration/http_authenticatable_test.rb +0 -105
  154. data/test/integration/lockable_test.rb +0 -239
  155. data/test/integration/omniauthable_test.rb +0 -133
  156. data/test/integration/recoverable_test.rb +0 -347
  157. data/test/integration/registerable_test.rb +0 -359
  158. data/test/integration/rememberable_test.rb +0 -176
  159. data/test/integration/timeoutable_test.rb +0 -189
  160. data/test/integration/trackable_test.rb +0 -92
  161. data/test/mailers/confirmation_instructions_test.rb +0 -115
  162. data/test/mailers/reset_password_instructions_test.rb +0 -96
  163. data/test/mailers/unlock_instructions_test.rb +0 -91
  164. data/test/mapping_test.rb +0 -134
  165. data/test/models/authenticatable_test.rb +0 -23
  166. data/test/models/confirmable_test.rb +0 -468
  167. data/test/models/database_authenticatable_test.rb +0 -249
  168. data/test/models/lockable_test.rb +0 -328
  169. data/test/models/omniauthable_test.rb +0 -7
  170. data/test/models/recoverable_test.rb +0 -228
  171. data/test/models/registerable_test.rb +0 -7
  172. data/test/models/rememberable_test.rb +0 -204
  173. data/test/models/serializable_test.rb +0 -49
  174. data/test/models/timeoutable_test.rb +0 -51
  175. data/test/models/trackable_test.rb +0 -41
  176. data/test/models/validatable_test.rb +0 -127
  177. data/test/models_test.rb +0 -144
  178. data/test/omniauth/config_test.rb +0 -57
  179. data/test/omniauth/url_helpers_test.rb +0 -54
  180. data/test/orm/active_record.rb +0 -10
  181. data/test/orm/mongoid.rb +0 -13
  182. data/test/parameter_sanitizer_test.rb +0 -81
  183. data/test/rails_app/Rakefile +0 -6
  184. data/test/rails_app/app/active_record/admin.rb +0 -6
  185. data/test/rails_app/app/active_record/shim.rb +0 -2
  186. data/test/rails_app/app/active_record/user.rb +0 -6
  187. data/test/rails_app/app/active_record/user_on_engine.rb +0 -7
  188. data/test/rails_app/app/active_record/user_on_main_app.rb +0 -7
  189. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  190. data/test/rails_app/app/controllers/admins_controller.rb +0 -11
  191. data/test/rails_app/app/controllers/application_controller.rb +0 -12
  192. data/test/rails_app/app/controllers/application_with_fake_engine.rb +0 -30
  193. data/test/rails_app/app/controllers/custom/registrations_controller.rb +0 -31
  194. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  195. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  196. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  197. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  198. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  199. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  200. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +0 -3
  201. data/test/rails_app/app/mailers/users/mailer.rb +0 -3
  202. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +0 -4
  203. data/test/rails_app/app/mongoid/admin.rb +0 -29
  204. data/test/rails_app/app/mongoid/shim.rb +0 -23
  205. data/test/rails_app/app/mongoid/user.rb +0 -39
  206. data/test/rails_app/app/mongoid/user_on_engine.rb +0 -39
  207. data/test/rails_app/app/mongoid/user_on_main_app.rb +0 -39
  208. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  209. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  210. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  211. data/test/rails_app/app/views/home/index.html.erb +0 -1
  212. data/test/rails_app/app/views/home/join.html.erb +0 -1
  213. data/test/rails_app/app/views/home/private.html.erb +0 -1
  214. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  215. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  216. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  217. data/test/rails_app/app/views/users/index.html.erb +0 -1
  218. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  219. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  220. data/test/rails_app/bin/bundle +0 -3
  221. data/test/rails_app/bin/rails +0 -4
  222. data/test/rails_app/bin/rake +0 -4
  223. data/test/rails_app/config/application.rb +0 -40
  224. data/test/rails_app/config/boot.rb +0 -14
  225. data/test/rails_app/config/database.yml +0 -18
  226. data/test/rails_app/config/environment.rb +0 -5
  227. data/test/rails_app/config/environments/development.rb +0 -30
  228. data/test/rails_app/config/environments/production.rb +0 -84
  229. data/test/rails_app/config/environments/test.rb +0 -41
  230. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  231. data/test/rails_app/config/initializers/devise.rb +0 -180
  232. data/test/rails_app/config/initializers/inflections.rb +0 -2
  233. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  234. data/test/rails_app/config/initializers/session_store.rb +0 -1
  235. data/test/rails_app/config/routes.rb +0 -122
  236. data/test/rails_app/config.ru +0 -4
  237. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
  238. data/test/rails_app/db/schema.rb +0 -55
  239. data/test/rails_app/lib/shared_admin.rb +0 -17
  240. data/test/rails_app/lib/shared_user.rb +0 -29
  241. data/test/rails_app/lib/shared_user_without_omniauth.rb +0 -13
  242. data/test/rails_app/public/404.html +0 -26
  243. data/test/rails_app/public/422.html +0 -26
  244. data/test/rails_app/public/500.html +0 -26
  245. data/test/rails_app/public/favicon.ico +0 -0
  246. data/test/rails_test.rb +0 -9
  247. data/test/routes_test.rb +0 -264
  248. data/test/support/action_controller/record_identifier.rb +0 -10
  249. data/test/support/assertions.rb +0 -39
  250. data/test/support/helpers.rb +0 -73
  251. data/test/support/integration.rb +0 -92
  252. data/test/support/locale/en.yml +0 -8
  253. data/test/support/mongoid.yml +0 -6
  254. data/test/support/webrat/integrations/rails.rb +0 -24
  255. data/test/test_helper.rb +0 -34
  256. data/test/test_helpers_test.rb +0 -178
  257. data/test/test_models.rb +0 -33
@@ -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.1".freeze
4
+ VERSION = "4.8.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'
@@ -8,22 +10,23 @@ require 'responders'
8
10
 
9
11
  module Devise
10
12
  autoload :Delegator, 'devise/delegator'
13
+ autoload :Encryptor, 'devise/encryptor'
11
14
  autoload :FailureApp, 'devise/failure_app'
12
15
  autoload :OmniAuth, 'devise/omniauth'
13
16
  autoload :ParameterFilter, 'devise/parameter_filter'
14
- autoload :BaseSanitizer, 'devise/parameter_sanitizer'
15
17
  autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
16
18
  autoload :TestHelpers, 'devise/test_helpers'
17
19
  autoload :TimeInflector, 'devise/time_inflector'
18
20
  autoload :TokenGenerator, 'devise/token_generator'
21
+ autoload :SecretKeyFinder, 'devise/secret_key_finder'
19
22
 
20
23
  module Controllers
21
- autoload :Helpers, 'devise/controllers/helpers'
22
- autoload :Rememberable, 'devise/controllers/rememberable'
23
- autoload :ScopedViews, 'devise/controllers/scoped_views'
24
- autoload :SignInOut, 'devise/controllers/sign_in_out'
25
- autoload :StoreLocation, 'devise/controllers/store_location'
26
- 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'
27
30
  end
28
31
 
29
32
  module Hooks
@@ -35,17 +38,22 @@ module Devise
35
38
  end
36
39
 
37
40
  module Strategies
38
- autoload :Base, 'devise/strategies/base'
41
+ autoload :Base, 'devise/strategies/base'
39
42
  autoload :Authenticatable, 'devise/strategies/authenticatable'
40
43
  end
41
44
 
45
+ module Test
46
+ autoload :ControllerHelpers, 'devise/test/controller_helpers'
47
+ autoload :IntegrationHelpers, 'devise/test/integration_helpers'
48
+ end
49
+
42
50
  # Constants which holds devise configuration for extensions. Those should
43
51
  # not be modified by the "end user" (this is why they are constants).
44
52
  ALL = []
45
- CONTROLLERS = ActiveSupport::OrderedHash.new
46
- ROUTES = ActiveSupport::OrderedHash.new
47
- STRATEGIES = ActiveSupport::OrderedHash.new
48
- URL_HELPERS = ActiveSupport::OrderedHash.new
53
+ CONTROLLERS = {}
54
+ ROUTES = {}
55
+ STRATEGIES = {}
56
+ URL_HELPERS = {}
49
57
 
50
58
  # Strategies that do not require user input.
51
59
  NO_INPUT = []
@@ -61,9 +69,9 @@ module Devise
61
69
  mattr_accessor :rememberable_options
62
70
  @@rememberable_options = {}
63
71
 
64
- # The number of times to encrypt password.
72
+ # The number of times to hash the password.
65
73
  mattr_accessor :stretches
66
- @@stretches = 10
74
+ @@stretches = 12
67
75
 
68
76
  # The default key used when authenticating over http auth.
69
77
  mattr_accessor :http_authentication_key
@@ -83,7 +91,7 @@ module Devise
83
91
 
84
92
  # Keys that should have whitespace stripped.
85
93
  mattr_accessor :strip_whitespace_keys
86
- @@strip_whitespace_keys = []
94
+ @@strip_whitespace_keys = [:email]
87
95
 
88
96
  # If http authentication is enabled by default.
89
97
  mattr_accessor :http_authenticatable
@@ -101,11 +109,11 @@ module Devise
101
109
  mattr_accessor :http_authentication_realm
102
110
  @@http_authentication_realm = "Application"
103
111
 
104
- # Email regex used to validate email formats. It simply asserts that
105
- # an one (and only one) @ exists in the given string. This is mainly
106
- # 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.
107
115
  mattr_accessor :email_regexp
108
- @@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
116
+ @@email_regexp = /\A[^@\s]+@[^@\s]+\z/
109
117
 
110
118
  # Range validation for password length
111
119
  mattr_accessor :password_length
@@ -137,22 +145,25 @@ module Devise
137
145
  @@confirmation_keys = [:email]
138
146
 
139
147
  # Defines if email should be reconfirmable.
140
- # False by default for backwards compatibility.
141
148
  mattr_accessor :reconfirmable
142
- @@reconfirmable = false
149
+ @@reconfirmable = true
143
150
 
144
151
  # Time interval to timeout the user session without activity.
145
152
  mattr_accessor :timeout_in
146
153
  @@timeout_in = 30.minutes
147
154
 
148
- # Authentication token expiration on timeout
149
- mattr_accessor :expire_auth_token_on_timeout
150
- @@expire_auth_token_on_timeout = false
151
-
152
- # Used to encrypt password. Please generate one with rake secret.
155
+ # Used to hash the password. Please generate one with rails secret.
153
156
  mattr_accessor :pepper
154
157
  @@pepper = nil
155
158
 
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.
164
+ mattr_accessor :send_password_change_notification
165
+ @@send_password_change_notification = false
166
+
156
167
  # Scoped views. Since it relies on fallbacks to render default views, it's
157
168
  # turned off by default.
158
169
  mattr_accessor :scoped_views
@@ -202,7 +213,7 @@ module Devise
202
213
 
203
214
  # Skip session storage for the following strategies
204
215
  mattr_accessor :skip_session_storage
205
- @@skip_session_storage = []
216
+ @@skip_session_storage = [:http_auth]
206
217
 
207
218
  # Which formats should be treated as navigational.
208
219
  mattr_accessor :navigational_formats
@@ -214,7 +225,7 @@ module Devise
214
225
 
215
226
  # The default method used while signing out
216
227
  mattr_accessor :sign_out_via
217
- @@sign_out_via = :get
228
+ @@sign_out_via = :delete
218
229
 
219
230
  # The parent controller all Devise controllers inherits from.
220
231
  # Defaults to ApplicationController. This should be set early
@@ -243,15 +254,22 @@ module Devise
243
254
  mattr_accessor :clean_up_csrf_token_on_authentication
244
255
  @@clean_up_csrf_token_on_authentication = true
245
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
+
246
264
  # PRIVATE CONFIGURATION
247
265
 
248
266
  # Store scopes mappings.
249
267
  mattr_reader :mappings
250
- @@mappings = ActiveSupport::OrderedHash.new
268
+ @@mappings = {}
251
269
 
252
270
  # OmniAuth configurations.
253
271
  mattr_reader :omniauth_configs
254
- @@omniauth_configs = ActiveSupport::OrderedHash.new
272
+ @@omniauth_configs = {}
255
273
 
256
274
  # Define a set of modules that are called when a mapping is added.
257
275
  mattr_reader :helpers
@@ -275,14 +293,22 @@ module Devise
275
293
  mattr_accessor :token_generator
276
294
  @@token_generator = nil
277
295
 
278
- # 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.activerecord51? # :nodoc:
301
+ defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
302
+ end
303
+
304
+ # Default way to set up Devise. Run rails generate devise_install to create
279
305
  # a fresh initializer with all configuration values.
280
306
  def self.setup
281
307
  yield self
282
308
  end
283
309
 
284
310
  class Getter
285
- def initialize name
311
+ def initialize(name)
286
312
  @name = name
287
313
  end
288
314
 
@@ -292,12 +318,8 @@ module Devise
292
318
  end
293
319
 
294
320
  def self.ref(arg)
295
- if defined?(ActiveSupport::Dependencies::ClassCache)
296
- ActiveSupport::Dependencies::reference(arg)
297
- Getter.new(arg)
298
- else
299
- ActiveSupport::Dependencies.ref(arg)
300
- end
321
+ ActiveSupport::Dependencies.reference(arg)
322
+ Getter.new(arg)
301
323
  end
302
324
 
303
325
  def self.available_router_name
@@ -328,7 +350,12 @@ module Devise
328
350
  mapping
329
351
  end
330
352
 
331
- # Make Devise aware of an 3rd party Devise-module (like invitable). For convenience.
353
+ # Register available devise modules. For the standard modules that Devise provides, this method is
354
+ # called from lib/devise/modules.rb. Third-party modules need to be added explicitly using this method.
355
+ #
356
+ # Note that adding a module using this method does not cause it to be used in the authentication
357
+ # process. That requires that the module be listed in the arguments passed to the 'devise' method
358
+ # in the model class definition.
332
359
  #
333
360
  # == Options:
334
361
  #
@@ -413,7 +440,6 @@ module Devise
413
440
  # config.omniauth :github, APP_ID, APP_SECRET
414
441
  #
415
442
  def self.omniauth(provider, *args)
416
- @@helpers << Devise::OmniAuth::UrlHelpers
417
443
  config = Devise::OmniAuth::Config.new(provider, args)
418
444
  @@omniauth_configs[config.strategy_name.to_sym] = config
419
445
  end
@@ -436,8 +462,8 @@ module Devise
436
462
  Devise::Controllers::UrlHelpers.generate_helpers!
437
463
  end
438
464
 
439
- # A method used internally to setup warden manager from the Rails initialize
440
- # block.
465
+ # A method used internally to complete the setup of warden manager after routes are loaded.
466
+ # See lib/devise/rails/routes.rb - ActionDispatch::Routing::RouteSet#finalize_with_devise!
441
467
  def self.configure_warden! #:nodoc:
442
468
  @@warden_configured ||= begin
443
469
  warden_config.failure_app = Devise::Delegator.new
@@ -451,10 +477,7 @@ module Devise
451
477
  mapping.to.serialize_into_session(record)
452
478
  end
453
479
 
454
- warden_config.serialize_from_session(mapping.name) do |key|
455
- # Previous versions contained an additional entry at the beginning of
456
- # key with the record's class name.
457
- args = key[-2, 2]
480
+ warden_config.serialize_from_session(mapping.name) do |args|
458
481
  mapping.to.serialize_from_session(*args)
459
482
  end
460
483
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/active_record'
2
4
  require 'generators/devise/orm_helpers'
3
5
 
@@ -6,14 +8,16 @@ module ActiveRecord
6
8
  class DeviseGenerator < ActiveRecord::Generators::Base
7
9
  argument :attributes, type: :array, default: [], banner: "field:type field:type"
8
10
 
11
+ class_option :primary_key_type, type: :string, desc: "The type for primary key"
12
+
9
13
  include Devise::Generators::OrmHelpers
10
14
  source_root File.expand_path("../templates", __FILE__)
11
15
 
12
16
  def copy_devise_migration
13
17
  if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
14
- migration_template "migration_existing.rb", "db/migrate/add_devise_to_#{table_name}.rb"
18
+ migration_template "migration_existing.rb", "#{migration_path}/add_devise_to_#{table_name}.rb", migration_version: migration_version
15
19
  else
16
- migration_template "migration.rb", "db/migrate/devise_create_#{table_name}.rb"
20
+ migration_template "migration.rb", "#{migration_path}/devise_create_#{table_name}.rb", migration_version: migration_version
17
21
  end
18
22
  end
19
23
 
@@ -50,11 +54,11 @@ module ActiveRecord
50
54
  t.datetime :remember_created_at
51
55
 
52
56
  ## Trackable
53
- t.integer :sign_in_count, default: 0, null: false
54
- t.datetime :current_sign_in_at
55
- t.datetime :last_sign_in_at
56
- t.#{ip_column} :current_sign_in_ip
57
- t.#{ip_column} :last_sign_in_ip
57
+ # t.integer :sign_in_count, default: 0, null: false
58
+ # t.datetime :current_sign_in_at
59
+ # t.datetime :last_sign_in_at
60
+ # t.#{ip_column} :current_sign_in_ip
61
+ # t.#{ip_column} :last_sign_in_ip
58
62
 
59
63
  ## Confirmable
60
64
  # t.string :confirmation_token
@@ -75,17 +79,47 @@ RUBY
75
79
  end
76
80
 
77
81
  def inet?
78
- rails4? && postgresql?
82
+ postgresql?
83
+ end
84
+
85
+ def rails5_and_up?
86
+ Rails::VERSION::MAJOR >= 5
79
87
  end
80
88
 
81
- def rails4?
82
- Rails.version.start_with? '4'
89
+ def rails61_and_up?
90
+ Rails::VERSION::MAJOR > 6 || (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1)
83
91
  end
84
92
 
85
93
  def postgresql?
86
- config = ActiveRecord::Base.configurations[Rails.env]
87
- config && config['adapter'] == 'postgresql'
94
+ ar_config && ar_config['adapter'] == 'postgresql'
88
95
  end
96
+
97
+ def ar_config
98
+ if ActiveRecord::Base.configurations.respond_to?(:configs_for)
99
+ if rails61_and_up?
100
+ ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: "primary").configuration_hash
101
+ else
102
+ ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: "primary").config
103
+ end
104
+ else
105
+ ActiveRecord::Base.configurations[Rails.env]
106
+ end
107
+ end
108
+
109
+ def migration_version
110
+ if rails5_and_up?
111
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
112
+ end
113
+ end
114
+
115
+ def primary_key_type
116
+ primary_key_string if rails5_and_up?
117
+ end
118
+
119
+ def primary_key_string
120
+ key_string = options[:primary_key_type]
121
+ ", id: :#{key_string}" if key_string
122
+ end
89
123
  end
90
124
  end
91
125
  end
@@ -1,6 +1,8 @@
1
- class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
4
  def change
3
- create_table(:<%= table_name %>) do |t|
5
+ create_table :<%= table_name %><%= primary_key_type %> do |t|
4
6
  <%= migration_data -%>
5
7
 
6
8
  <% attributes.each do |attribute| -%>
@@ -1,6 +1,8 @@
1
- class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
4
  def self.up
3
- change_table(:<%= table_name %>) do |t|
5
+ change_table :<%= table_name %> do |t|
4
6
  <%= migration_data -%>
5
7
 
6
8
  <% attributes.each do |attribute| -%>
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/base'
2
4
 
3
5
  module Devise
@@ -16,7 +18,7 @@ module Devise
16
18
 
17
19
  This will create a controller class at app/controllers/users/sessions_controller.rb like this:
18
20
 
19
- class Users::ConfirmationsController < Devise::ConfirmationsController
21
+ class Users::SessionsController < Devise::SessionsController
20
22
  content...
21
23
  end
22
24
  DESC
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/named_base'
2
4
 
3
5
  module Devise
@@ -8,15 +10,15 @@ module Devise
8
10
  namespace "devise"
9
11
  source_root File.expand_path("../templates", __FILE__)
10
12
 
11
- desc "Generates a model with the given NAME (if one does not exist) with devise " <<
13
+ desc "Generates a model with the given NAME (if one does not exist) with devise " \
12
14
  "configuration plus a migration file and devise routes."
13
15
 
14
- hook_for :orm
16
+ hook_for :orm, required: true
15
17
 
16
18
  class_option :routes, desc: "Generate routes", type: :boolean, default: true
17
19
 
18
20
  def add_devise_routes
19
- devise_route = "devise_for :#{plural_name}"
21
+ devise_route = "devise_for :#{plural_name}".dup
20
22
  devise_route << %Q(, class_name: "#{class_name}") if class_name.include?("::")
21
23
  devise_route << %Q(, skip: :all) unless options.routes?
22
24
  route devise_route
@@ -1,15 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/base'
2
4
  require 'securerandom'
3
5
 
4
6
  module Devise
5
7
  module Generators
8
+ MissingORMError = Class.new(Thor::Error)
9
+
6
10
  class InstallGenerator < Rails::Generators::Base
7
11
  source_root File.expand_path("../../templates", __FILE__)
8
12
 
9
13
  desc "Creates a Devise initializer and copy locale files to your application."
10
- class_option :orm
14
+ class_option :orm, required: true
11
15
 
12
16
  def copy_initializer
17
+ unless options[:orm]
18
+ raise MissingORMError, <<-ERROR.strip_heredoc
19
+ An ORM must be set to install Devise in your application.
20
+
21
+ Be sure to have an ORM like Active Record or Mongoid loaded in your
22
+ app or configure your own at `config/application.rb`.
23
+
24
+ config.generators do |g|
25
+ g.orm :your_orm_gem
26
+ end
27
+ ERROR
28
+ end
29
+
13
30
  template "devise.rb", "config/initializers/devise.rb"
14
31
  end
15
32
 
@@ -20,10 +37,6 @@ module Devise
20
37
  def show_readme
21
38
  readme "README" if behavior == :invoke
22
39
  end
23
-
24
- def rails_4?
25
- Rails::VERSION::MAJOR == 4
26
- end
27
40
  end
28
41
  end
29
42
  end