devise 3.2.2 → 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 (235) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +242 -978
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +371 -100
  5. data/app/controllers/devise/confirmations_controller.rb +11 -5
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +12 -6
  7. data/app/controllers/devise/passwords_controller.rb +21 -8
  8. data/app/controllers/devise/registrations_controller.rb +59 -26
  9. data/app/controllers/devise/sessions_controller.rb +47 -17
  10. data/app/controllers/devise/unlocks_controller.rb +9 -4
  11. data/app/controllers/devise_controller.rb +67 -31
  12. data/app/helpers/devise_helper.rb +12 -19
  13. data/app/mailers/devise/mailer.rb +10 -0
  14. data/app/views/devise/confirmations/new.html.erb +9 -5
  15. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  16. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  17. data/app/views/devise/mailer/password_change.html.erb +3 -0
  18. data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
  19. data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
  20. data/app/views/devise/passwords/edit.html.erb +16 -7
  21. data/app/views/devise/passwords/new.html.erb +9 -5
  22. data/app/views/devise/registrations/edit.html.erb +29 -15
  23. data/app/views/devise/registrations/new.html.erb +20 -9
  24. data/app/views/devise/sessions/new.html.erb +19 -10
  25. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  26. data/app/views/devise/shared/{_links.erb → _links.html.erb} +9 -9
  27. data/app/views/devise/unlocks/new.html.erb +9 -5
  28. data/config/locales/en.yml +23 -17
  29. data/lib/devise/controllers/helpers.rb +112 -32
  30. data/lib/devise/controllers/rememberable.rb +15 -6
  31. data/lib/devise/controllers/scoped_views.rb +3 -1
  32. data/lib/devise/controllers/sign_in_out.rb +42 -26
  33. data/lib/devise/controllers/store_location.rb +31 -5
  34. data/lib/devise/controllers/url_helpers.rb +9 -7
  35. data/lib/devise/delegator.rb +2 -0
  36. data/lib/devise/encryptor.rb +24 -0
  37. data/lib/devise/failure_app.rb +125 -39
  38. data/lib/devise/hooks/activatable.rb +7 -6
  39. data/lib/devise/hooks/csrf_cleaner.rb +5 -1
  40. data/lib/devise/hooks/forgetable.rb +2 -0
  41. data/lib/devise/hooks/lockable.rb +7 -2
  42. data/lib/devise/hooks/proxy.rb +4 -2
  43. data/lib/devise/hooks/rememberable.rb +4 -2
  44. data/lib/devise/hooks/timeoutable.rb +16 -9
  45. data/lib/devise/hooks/trackable.rb +3 -1
  46. data/lib/devise/mailers/helpers.rb +15 -12
  47. data/lib/devise/mapping.rb +8 -2
  48. data/lib/devise/models/authenticatable.rb +82 -56
  49. data/lib/devise/models/confirmable.rb +125 -42
  50. data/lib/devise/models/database_authenticatable.rb +110 -32
  51. data/lib/devise/models/lockable.rb +30 -17
  52. data/lib/devise/models/omniauthable.rb +3 -1
  53. data/lib/devise/models/recoverable.rb +62 -26
  54. data/lib/devise/models/registerable.rb +4 -0
  55. data/lib/devise/models/rememberable.rb +62 -33
  56. data/lib/devise/models/timeoutable.rb +4 -8
  57. data/lib/devise/models/trackable.rb +20 -4
  58. data/lib/devise/models/validatable.rb +16 -9
  59. data/lib/devise/models.rb +3 -1
  60. data/lib/devise/modules.rb +12 -10
  61. data/lib/devise/omniauth/config.rb +2 -0
  62. data/lib/devise/omniauth/url_helpers.rb +14 -5
  63. data/lib/devise/omniauth.rb +2 -0
  64. data/lib/devise/orm/active_record.rb +5 -1
  65. data/lib/devise/orm/mongoid.rb +6 -2
  66. data/lib/devise/parameter_filter.rb +4 -0
  67. data/lib/devise/parameter_sanitizer.rb +139 -65
  68. data/lib/devise/rails/routes.rb +147 -116
  69. data/lib/devise/rails/warden_compat.rb +3 -10
  70. data/lib/devise/rails.rb +10 -13
  71. data/lib/devise/secret_key_finder.rb +27 -0
  72. data/lib/devise/strategies/authenticatable.rb +20 -9
  73. data/lib/devise/strategies/base.rb +3 -1
  74. data/lib/devise/strategies/database_authenticatable.rb +14 -6
  75. data/lib/devise/strategies/rememberable.rb +15 -3
  76. data/lib/devise/test/controller_helpers.rb +165 -0
  77. data/lib/devise/test/integration_helpers.rb +63 -0
  78. data/lib/devise/test_helpers.rb +7 -124
  79. data/lib/devise/time_inflector.rb +4 -2
  80. data/lib/devise/token_generator.rb +3 -41
  81. data/lib/devise/version.rb +3 -1
  82. data/lib/devise.rb +111 -84
  83. data/lib/generators/active_record/devise_generator.rb +49 -12
  84. data/lib/generators/active_record/templates/migration.rb +9 -7
  85. data/lib/generators/active_record/templates/migration_existing.rb +9 -7
  86. data/lib/generators/devise/controllers_generator.rb +46 -0
  87. data/lib/generators/devise/devise_generator.rb +7 -5
  88. data/lib/generators/devise/install_generator.rb +21 -0
  89. data/lib/generators/devise/orm_helpers.rb +10 -21
  90. data/lib/generators/devise/views_generator.rb +49 -28
  91. data/lib/generators/mongoid/devise_generator.rb +21 -19
  92. data/lib/generators/templates/README +5 -12
  93. data/lib/generators/templates/controllers/README +14 -0
  94. data/lib/generators/templates/controllers/confirmations_controller.rb +30 -0
  95. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +30 -0
  96. data/lib/generators/templates/controllers/passwords_controller.rb +34 -0
  97. data/lib/generators/templates/controllers/registrations_controller.rb +62 -0
  98. data/lib/generators/templates/controllers/sessions_controller.rb +27 -0
  99. data/lib/generators/templates/controllers/unlocks_controller.rb +30 -0
  100. data/lib/generators/templates/devise.rb +81 -36
  101. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  102. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  103. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  104. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  105. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  106. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +6 -2
  107. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +9 -4
  108. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +5 -2
  109. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +14 -6
  110. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +12 -4
  111. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +11 -6
  112. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +5 -2
  113. metadata +52 -280
  114. data/.gitignore +0 -10
  115. data/.travis.yml +0 -20
  116. data/.yardopts +0 -9
  117. data/CONTRIBUTING.md +0 -14
  118. data/Gemfile +0 -31
  119. data/Gemfile.lock +0 -160
  120. data/Rakefile +0 -35
  121. data/devise.gemspec +0 -27
  122. data/devise.png +0 -0
  123. data/gemfiles/Gemfile.rails-3.2.x +0 -31
  124. data/gemfiles/Gemfile.rails-3.2.x.lock +0 -159
  125. data/test/controllers/custom_strategy_test.rb +0 -62
  126. data/test/controllers/helpers_test.rb +0 -276
  127. data/test/controllers/internal_helpers_test.rb +0 -120
  128. data/test/controllers/passwords_controller_test.rb +0 -31
  129. data/test/controllers/sessions_controller_test.rb +0 -99
  130. data/test/controllers/url_helpers_test.rb +0 -59
  131. data/test/delegator_test.rb +0 -19
  132. data/test/devise_test.rb +0 -94
  133. data/test/failure_app_test.rb +0 -232
  134. data/test/generators/active_record_generator_test.rb +0 -103
  135. data/test/generators/devise_generator_test.rb +0 -39
  136. data/test/generators/install_generator_test.rb +0 -13
  137. data/test/generators/mongoid_generator_test.rb +0 -23
  138. data/test/generators/views_generator_test.rb +0 -67
  139. data/test/helpers/devise_helper_test.rb +0 -51
  140. data/test/integration/authenticatable_test.rb +0 -713
  141. data/test/integration/confirmable_test.rb +0 -284
  142. data/test/integration/database_authenticatable_test.rb +0 -84
  143. data/test/integration/http_authenticatable_test.rb +0 -105
  144. data/test/integration/lockable_test.rb +0 -239
  145. data/test/integration/omniauthable_test.rb +0 -133
  146. data/test/integration/recoverable_test.rb +0 -334
  147. data/test/integration/registerable_test.rb +0 -349
  148. data/test/integration/rememberable_test.rb +0 -167
  149. data/test/integration/timeoutable_test.rb +0 -183
  150. data/test/integration/trackable_test.rb +0 -92
  151. data/test/mailers/confirmation_instructions_test.rb +0 -115
  152. data/test/mailers/reset_password_instructions_test.rb +0 -96
  153. data/test/mailers/unlock_instructions_test.rb +0 -91
  154. data/test/mapping_test.rb +0 -127
  155. data/test/models/authenticatable_test.rb +0 -13
  156. data/test/models/confirmable_test.rb +0 -454
  157. data/test/models/database_authenticatable_test.rb +0 -249
  158. data/test/models/lockable_test.rb +0 -298
  159. data/test/models/omniauthable_test.rb +0 -7
  160. data/test/models/recoverable_test.rb +0 -184
  161. data/test/models/registerable_test.rb +0 -7
  162. data/test/models/rememberable_test.rb +0 -183
  163. data/test/models/serializable_test.rb +0 -49
  164. data/test/models/timeoutable_test.rb +0 -51
  165. data/test/models/trackable_test.rb +0 -13
  166. data/test/models/validatable_test.rb +0 -127
  167. data/test/models_test.rb +0 -144
  168. data/test/omniauth/config_test.rb +0 -57
  169. data/test/omniauth/url_helpers_test.rb +0 -54
  170. data/test/orm/active_record.rb +0 -10
  171. data/test/orm/mongoid.rb +0 -13
  172. data/test/parameter_sanitizer_test.rb +0 -81
  173. data/test/rails_app/Rakefile +0 -6
  174. data/test/rails_app/app/active_record/admin.rb +0 -6
  175. data/test/rails_app/app/active_record/shim.rb +0 -2
  176. data/test/rails_app/app/active_record/user.rb +0 -6
  177. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  178. data/test/rails_app/app/controllers/admins_controller.rb +0 -11
  179. data/test/rails_app/app/controllers/application_controller.rb +0 -9
  180. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  181. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  182. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  183. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  184. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  185. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  186. data/test/rails_app/app/mailers/users/mailer.rb +0 -12
  187. data/test/rails_app/app/mongoid/admin.rb +0 -29
  188. data/test/rails_app/app/mongoid/shim.rb +0 -23
  189. data/test/rails_app/app/mongoid/user.rb +0 -39
  190. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  191. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  192. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  193. data/test/rails_app/app/views/home/index.html.erb +0 -1
  194. data/test/rails_app/app/views/home/join.html.erb +0 -1
  195. data/test/rails_app/app/views/home/private.html.erb +0 -1
  196. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  197. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  198. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  199. data/test/rails_app/app/views/users/index.html.erb +0 -1
  200. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  201. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  202. data/test/rails_app/bin/bundle +0 -3
  203. data/test/rails_app/bin/rails +0 -4
  204. data/test/rails_app/bin/rake +0 -4
  205. data/test/rails_app/config/application.rb +0 -40
  206. data/test/rails_app/config/boot.rb +0 -14
  207. data/test/rails_app/config/database.yml +0 -18
  208. data/test/rails_app/config/environment.rb +0 -5
  209. data/test/rails_app/config/environments/development.rb +0 -30
  210. data/test/rails_app/config/environments/production.rb +0 -80
  211. data/test/rails_app/config/environments/test.rb +0 -36
  212. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  213. data/test/rails_app/config/initializers/devise.rb +0 -181
  214. data/test/rails_app/config/initializers/inflections.rb +0 -2
  215. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  216. data/test/rails_app/config/initializers/session_store.rb +0 -1
  217. data/test/rails_app/config/routes.rb +0 -104
  218. data/test/rails_app/config.ru +0 -4
  219. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
  220. data/test/rails_app/db/schema.rb +0 -55
  221. data/test/rails_app/lib/shared_admin.rb +0 -17
  222. data/test/rails_app/lib/shared_user.rb +0 -29
  223. data/test/rails_app/public/404.html +0 -26
  224. data/test/rails_app/public/422.html +0 -26
  225. data/test/rails_app/public/500.html +0 -26
  226. data/test/rails_app/public/favicon.ico +0 -0
  227. data/test/routes_test.rb +0 -250
  228. data/test/support/assertions.rb +0 -40
  229. data/test/support/helpers.rb +0 -70
  230. data/test/support/integration.rb +0 -92
  231. data/test/support/locale/en.yml +0 -8
  232. data/test/support/webrat/integrations/rails.rb +0 -24
  233. data/test/test_helper.rb +0 -27
  234. data/test/test_helpers_test.rb +0 -173
  235. data/test/test_models.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Controllers
3
5
  # Those helpers are convenience methods added to ApplicationController.
@@ -7,10 +9,76 @@ module Devise
7
9
  include Devise::Controllers::StoreLocation
8
10
 
9
11
  included do
10
- helper_method :warden, :signed_in?, :devise_controller?
12
+ if respond_to?(:helper_method)
13
+ helper_method :warden, :signed_in?, :devise_controller?
14
+ end
11
15
  end
12
16
 
13
17
  module ClassMethods
18
+ # Define authentication filters and accessor helpers for a group of mappings.
19
+ # These methods are useful when you are working with multiple mappings that
20
+ # share some functionality. They are pretty much the same as the ones
21
+ # defined for normal mappings.
22
+ #
23
+ # Example:
24
+ #
25
+ # inside BlogsController (or any other controller, it doesn't matter which):
26
+ # devise_group :blogger, contains: [:user, :admin]
27
+ #
28
+ # Generated methods:
29
+ # authenticate_blogger! # Redirects unless user or admin are signed in
30
+ # blogger_signed_in? # Checks whether there is either a user or an admin signed in
31
+ # current_blogger # Currently signed in user or admin
32
+ # current_bloggers # Currently signed in user and admin
33
+ #
34
+ # Use:
35
+ # before_action :authenticate_blogger! # Redirects unless either a user or an admin are authenticated
36
+ # before_action ->{ authenticate_blogger! :admin } # Redirects to the admin login page
37
+ # current_blogger :user # Preferably returns a User if one is signed in
38
+ #
39
+ def devise_group(group_name, opts={})
40
+ mappings = "[#{ opts[:contains].map { |m| ":#{m}" }.join(',') }]"
41
+
42
+ class_eval <<-METHODS, __FILE__, __LINE__ + 1
43
+ def authenticate_#{group_name}!(favourite=nil, opts={})
44
+ unless #{group_name}_signed_in?
45
+ mappings = #{mappings}
46
+ mappings.unshift mappings.delete(favourite.to_sym) if favourite
47
+ mappings.each do |mapping|
48
+ opts[:scope] = mapping
49
+ warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
50
+ end
51
+ end
52
+ end
53
+
54
+ def #{group_name}_signed_in?
55
+ #{mappings}.any? do |mapping|
56
+ warden.authenticate?(scope: mapping)
57
+ end
58
+ end
59
+
60
+ def current_#{group_name}(favourite=nil)
61
+ mappings = #{mappings}
62
+ mappings.unshift mappings.delete(favourite.to_sym) if favourite
63
+ mappings.each do |mapping|
64
+ current = warden.authenticate(scope: mapping)
65
+ return current if current
66
+ end
67
+ nil
68
+ end
69
+
70
+ def current_#{group_name.to_s.pluralize}
71
+ #{mappings}.map do |mapping|
72
+ warden.authenticate(scope: mapping)
73
+ end.compact
74
+ end
75
+
76
+ if respond_to?(:helper_method)
77
+ helper_method "current_#{group_name}", "current_#{group_name.to_s.pluralize}", "#{group_name}_signed_in?"
78
+ end
79
+ METHODS
80
+ end
81
+
14
82
  def log_process_action(payload)
15
83
  payload[:status] ||= 401 unless payload[:exception]
16
84
  super
@@ -18,7 +86,7 @@ module Devise
18
86
  end
19
87
 
20
88
  # Define authentication filters and accessor helpers based on mappings.
21
- # These filters should be used inside the controllers as before_filters,
89
+ # These filters should be used inside the controllers as before_actions,
22
90
  # so you can control the scope of the user who should be signed in to
23
91
  # access that specific controller/action.
24
92
  # Example:
@@ -38,8 +106,8 @@ module Devise
38
106
  # admin_session # Session data available only to the admin scope
39
107
  #
40
108
  # Use:
41
- # before_filter :authenticate_user! # Tell devise to use :user map
42
- # before_filter :authenticate_admin! # Tell devise to use :admin map
109
+ # before_action :authenticate_user! # Tell devise to use :user map
110
+ # before_action :authenticate_admin! # Tell devise to use :admin map
43
111
  #
44
112
  def self.define_helpers(mapping) #:nodoc:
45
113
  mapping = mapping.name
@@ -55,7 +123,7 @@ module Devise
55
123
  end
56
124
 
57
125
  def current_#{mapping}
58
- @current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
126
+ @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
59
127
  end
60
128
 
61
129
  def #{mapping}_session
@@ -64,33 +132,31 @@ module Devise
64
132
  METHODS
65
133
 
66
134
  ActiveSupport.on_load(:action_controller) do
67
- helper_method "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session"
135
+ if respond_to?(:helper_method)
136
+ helper_method "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session"
137
+ end
68
138
  end
69
139
  end
70
140
 
71
141
  # The main accessor for the warden proxy instance
72
142
  def warden
73
- request.env['warden']
143
+ request.env['warden'] or raise MissingWarden
74
144
  end
75
145
 
76
146
  # Return true if it's a devise_controller. false to all controllers unless
77
147
  # the controllers defined inside devise. Useful if you want to apply a before
78
148
  # filter to all controllers, except the ones in devise:
79
149
  #
80
- # before_filter :my_filter, :unless => :devise_controller?
150
+ # before_action :my_filter, unless: :devise_controller?
81
151
  def devise_controller?
82
- is_a?(DeviseController)
152
+ is_a?(::DeviseController)
83
153
  end
84
154
 
85
- # Setup a param sanitizer to filter parameters using strong_parameters. See
155
+ # Set up a param sanitizer to filter parameters using strong_parameters. See
86
156
  # lib/devise/parameter_sanitizer.rb for more info. Override this
87
157
  # method in your application controller to use your own parameter sanitizer.
88
158
  def devise_parameter_sanitizer
89
- @devise_parameter_sanitizer ||= if defined?(ActionController::StrongParameters)
90
- Devise::ParameterSanitizer.new(resource_class, resource_name, params)
91
- else
92
- Devise::BaseSanitizer.new(resource_class, resource_name, params)
93
- end
159
+ @devise_parameter_sanitizer ||= Devise::ParameterSanitizer.new(resource_class, resource_name, params)
94
160
  end
95
161
 
96
162
  # Tell warden that params authentication is allowed for that specific page.
@@ -98,13 +164,20 @@ module Devise
98
164
  request.env["devise.allow_params_authentication"] = true
99
165
  end
100
166
 
101
- # The scope root url to be used when he's signed in. By default, it first
167
+ # The scope root url to be used when they're signed in. By default, it first
102
168
  # tries to find a resource_root_path, otherwise it uses the root_path.
103
169
  def signed_in_root_path(resource_or_scope)
104
170
  scope = Devise::Mapping.find_scope!(resource_or_scope)
171
+ router_name = Devise.mappings[scope].router_name
172
+
105
173
  home_path = "#{scope}_root_path"
106
- if respond_to?(home_path, true)
107
- send(home_path)
174
+
175
+ context = router_name ? send(router_name) : self
176
+
177
+ if context.respond_to?(home_path, true)
178
+ context.send(home_path)
179
+ elsif context.respond_to?(:root_path)
180
+ context.root_path
108
181
  elsif respond_to?(:root_path)
109
182
  root_path
110
183
  else
@@ -121,10 +194,10 @@ module Devise
121
194
  # root path. For a user scope, you can define the default url in
122
195
  # the following way:
123
196
  #
124
- # map.user_root '/users', :controller => 'users' # creates user_root_path
197
+ # get '/users' => 'users#index', as: :user_root # creates user_root_path
125
198
  #
126
- # map.namespace :user do |user|
127
- # user.root :controller => 'users' # creates user_root_path
199
+ # namespace :user do
200
+ # root 'users#index' # creates user_root_path
128
201
  # end
129
202
  #
130
203
  # If the resource root path is not defined, root_path is used. However,
@@ -150,7 +223,10 @@ module Devise
150
223
  #
151
224
  # By default it is the root_path.
152
225
  def after_sign_out_path_for(resource_or_scope)
153
- respond_to?(:root_path) ? root_path : "/"
226
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
227
+ router_name = Devise.mappings[scope].router_name
228
+ context = router_name ? send(router_name) : self
229
+ context.respond_to?(:root_path) ? context.root_path : "/"
154
230
  end
155
231
 
156
232
  # Sign in a user and tries to redirect first to the stored location and
@@ -176,10 +252,9 @@ module Devise
176
252
  # Overwrite Rails' handle unverified request to sign out all scopes,
177
253
  # clear run strategies and remove cached variables.
178
254
  def handle_unverified_request
179
- sign_out_all_scopes(false)
255
+ super # call the default behaviour which resets/nullifies/raises
180
256
  request.env["devise.skip_storage"] = true
181
- expire_data_after_sign_out!
182
- super # call the default behaviour which resets the session
257
+ sign_out_all_scopes(false)
183
258
  end
184
259
 
185
260
  def request_format
@@ -193,21 +268,26 @@ module Devise
193
268
  # Check if flash messages should be emitted. Default is to do it on
194
269
  # navigational formats
195
270
  def is_flashing_format?
196
- is_navigational_format?
271
+ request.respond_to?(:flash) && is_navigational_format?
197
272
  end
198
273
 
199
274
  private
200
275
 
201
- def expire_session_data_after_sign_in!
202
- ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated " \
203
- "in favor of expire_data_after_sign_in!"
204
- expire_data_after_sign_in!
205
- end
206
-
207
276
  def expire_data_after_sign_out!
208
277
  Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
209
278
  super
210
279
  end
211
280
  end
212
281
  end
282
+
283
+ class MissingWarden < StandardError
284
+ def initialize
285
+ super "Devise could not find the `Warden::Proxy` instance on your request environment.\n" + \
286
+ "Make sure that your application is loading Devise and Warden as expected and that " + \
287
+ "the `Warden::Manager` middleware is present in your middleware stack.\n" + \
288
+ "If you are seeing this on one of your tests, ensure that your tests are either " + \
289
+ "executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` " + \
290
+ "module to inject the `request.env['warden']` object for you."
291
+ end
292
+ end
213
293
  end
@@ -1,19 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Controllers
3
5
  # A module that may be optionally included in a controller in order
4
6
  # to provide remember me behavior. Useful when signing in is done
5
- # through a callback, like in Omniauth.
7
+ # through a callback, like in OmniAuth.
6
8
  module Rememberable
7
9
  # Return default cookie values retrieved from session options.
8
10
  def self.cookie_values
9
11
  Rails.configuration.session_options.slice(:path, :domain, :secure)
10
12
  end
11
13
 
14
+ def remember_me_is_active?(resource)
15
+ return false unless resource.respond_to?(:remember_me)
16
+ scope = Devise::Mapping.find_scope!(resource)
17
+ _, token, generated_at = cookies.signed[remember_key(resource, scope)]
18
+ resource.remember_me?(token, generated_at)
19
+ end
20
+
12
21
  # Remembers the given resource by setting up a cookie
13
22
  def remember_me(resource)
14
- return if env["devise.skip_storage"]
23
+ return if request.env["devise.skip_storage"]
15
24
  scope = Devise::Mapping.find_scope!(resource)
16
- resource.remember_me!(resource.extend_remember_period)
25
+ resource.remember_me!
17
26
  cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource)
18
27
  end
19
28
 
@@ -31,11 +40,11 @@ module Devise
31
40
  end
32
41
 
33
42
  def remember_cookie_values(resource)
34
- options = { :httponly => true }
43
+ options = { httponly: true }
35
44
  options.merge!(forget_cookie_values(resource))
36
45
  options.merge!(
37
- :value => resource.class.serialize_into_cookie(resource),
38
- :expires => resource.remember_expires_at
46
+ value: resource.class.serialize_into_cookie(resource),
47
+ expires: resource.remember_expires_at
39
48
  )
40
49
  end
41
50
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Controllers
3
5
  module ScopedViews
@@ -14,4 +16,4 @@ module Devise
14
16
  end
15
17
  end
16
18
  end
17
- end
19
+ end
@@ -1,31 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Controllers
3
5
  # Provide sign in and sign out functionality.
4
6
  # Included by default in all controllers.
5
7
  module SignInOut
6
8
  # Return true if the given scope is signed in session. If no scope given, return
7
- # true if any scope is signed in. Does not run authentication hooks.
9
+ # true if any scope is signed in. This will run authentication hooks, which may
10
+ # cause exceptions to be thrown from this method; if you simply want to check
11
+ # if a scope has already previously been authenticated without running
12
+ # authentication hooks, you can directly call `warden.authenticated?(scope: scope)`
8
13
  def signed_in?(scope=nil)
9
- [ scope || Devise.mappings.keys ].flatten.any? do |_scope|
10
- warden.authenticate?(:scope => _scope)
14
+ [scope || Devise.mappings.keys].flatten.any? do |_scope|
15
+ warden.authenticate?(scope: _scope)
11
16
  end
12
17
  end
13
18
 
14
19
  # Sign in a user that already was authenticated. This helper is useful for logging
15
- # users in after sign up.
16
- #
17
- # All options given to sign_in is passed forward to the set_user method in warden.
18
- # The only exception is the :bypass option, which bypass warden callbacks and stores
19
- # the user straight in session. This option is useful in cases the user is already
20
- # signed in, but we want to refresh the credentials in session.
20
+ # users in after sign up. All options given to sign_in is passed forward
21
+ # to the set_user method in warden.
22
+ # If you are using a custom warden strategy and the timeoutable module, you have to
23
+ # set `env["devise.skip_timeout"] = true` in the request to use this method, like we do
24
+ # in the sessions controller: https://github.com/plataformatec/devise/blob/master/app/controllers/devise/sessions_controller.rb#L7
21
25
  #
22
26
  # Examples:
23
27
  #
24
28
  # sign_in :user, @user # sign_in(scope, resource)
25
29
  # sign_in @user # sign_in(resource)
26
- # sign_in @user, :event => :authentication # sign_in(resource, options)
27
- # sign_in @user, :store => false # sign_in(resource, options)
28
- # sign_in @user, :bypass => true # sign_in(resource, options)
30
+ # sign_in @user, event: :authentication # sign_in(resource, options)
31
+ # sign_in @user, store: false # sign_in(resource, options)
29
32
  #
30
33
  def sign_in(resource_or_scope, *args)
31
34
  options = args.extract_options!
@@ -35,15 +38,36 @@ module Devise
35
38
  expire_data_after_sign_in!
36
39
 
37
40
  if options[:bypass]
41
+ ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
42
+ [Devise] bypass option is deprecated and it will be removed in future version of Devise.
43
+ Please use bypass_sign_in method instead.
44
+ Example:
45
+
46
+ bypass_sign_in(user)
47
+ DEPRECATION
38
48
  warden.session_serializer.store(resource, scope)
39
49
  elsif warden.user(scope) == resource && !options.delete(:force)
40
50
  # Do nothing. User already signed in and we are not forcing it.
41
51
  true
42
52
  else
43
- warden.set_user(resource, options.merge!(:scope => scope))
53
+ warden.set_user(resource, options.merge!(scope: scope))
44
54
  end
45
55
  end
46
56
 
57
+ # Sign in a user bypassing the warden callbacks and stores the user
58
+ # straight in session. This option is useful in cases the user is already
59
+ # signed in, but we want to refresh the credentials in session.
60
+ #
61
+ # Examples:
62
+ #
63
+ # bypass_sign_in @user, scope: :user
64
+ # bypass_sign_in @user
65
+ def bypass_sign_in(resource, scope: nil)
66
+ scope ||= Devise::Mapping.find_scope!(resource)
67
+ expire_data_after_sign_in!
68
+ warden.session_serializer.store(resource, scope)
69
+ end
70
+
47
71
  # Sign out a given user or scope. This helper is useful for signing out a user
48
72
  # after deleting accounts. Returns true if there was a logout and false if there
49
73
  # is no user logged in on the referred scope
@@ -56,11 +80,10 @@ module Devise
56
80
  def sign_out(resource_or_scope=nil)
57
81
  return sign_out_all_scopes unless resource_or_scope
58
82
  scope = Devise::Mapping.find_scope!(resource_or_scope)
59
- user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
83
+ user = warden.user(scope: scope, run_callbacks: false) # If there is no user
60
84
 
61
- warden.raw_session.inspect # Without this inspect here. The session does not clear.
62
85
  warden.logout(scope)
63
- warden.clear_strategies_cache!(:scope => scope)
86
+ warden.clear_strategies_cache!(scope: scope)
64
87
  instance_variable_set(:"@current_#{scope}", nil)
65
88
 
66
89
  !!user
@@ -70,9 +93,8 @@ module Devise
70
93
  # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
71
94
  # and false if there was no user logged in on all scopes.
72
95
  def sign_out_all_scopes(lock=true)
73
- users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
96
+ users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
74
97
 
75
- warden.raw_session.inspect
76
98
  warden.logout
77
99
  expire_data_after_sign_out!
78
100
  warden.clear_strategies_cache!
@@ -91,13 +113,7 @@ module Devise
91
113
  session.keys.grep(/^devise\./).each { |k| session.delete(k) }
92
114
  end
93
115
 
94
- def expire_data_after_sign_out!
95
- # session.keys will return an empty array if the session is not yet loaded.
96
- # This is a bug in both Rack and Rails.
97
- # A call to #empty? forces the session to be loaded.
98
- session.empty?
99
- session.keys.grep(/^devise\./).each { |k| session.delete(k) }
100
- end
116
+ alias :expire_data_after_sign_out! :expire_data_after_sign_in!
101
117
  end
102
118
  end
103
- end
119
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
4
 
3
5
  module Devise
@@ -29,22 +31,46 @@ module Devise
29
31
  # Example:
30
32
  #
31
33
  # store_location_for(:user, dashboard_path)
32
- # redirect_to user_omniauth_authorize_path(:facebook)
34
+ # redirect_to user_facebook_omniauth_authorize_path
33
35
  #
34
36
  def store_location_for(resource_or_scope, location)
35
37
  session_key = stored_location_key_for(resource_or_scope)
36
- if location
37
- uri = URI.parse(location)
38
- session[session_key] = [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
39
- end
38
+
39
+ path = extract_path_from_location(location)
40
+ session[session_key] = path if path
40
41
  end
41
42
 
42
43
  private
43
44
 
45
+ def parse_uri(location)
46
+ location && URI.parse(location)
47
+ rescue URI::InvalidURIError
48
+ nil
49
+ end
50
+
44
51
  def stored_location_key_for(resource_or_scope)
45
52
  scope = Devise::Mapping.find_scope!(resource_or_scope)
46
53
  "#{scope}_return_to"
47
54
  end
55
+
56
+ def extract_path_from_location(location)
57
+ uri = parse_uri(location)
58
+
59
+ if uri
60
+ path = remove_domain_from_uri(uri)
61
+ path = add_fragment_back_to_path(uri, path)
62
+
63
+ path
64
+ end
65
+ end
66
+
67
+ def remove_domain_from_uri(uri)
68
+ [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
69
+ end
70
+
71
+ def add_fragment_back_to_path(uri, path)
72
+ [path, uri.fragment].compact.join('#')
73
+ end
48
74
  end
49
75
  end
50
76
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Controllers
3
5
  # Create url helpers to be used with resource/scope configuration. Acts as
@@ -42,14 +44,14 @@ module Devise
42
44
  [:path, :url].each do |path_or_url|
43
45
  actions.each do |action|
44
46
  action = action ? "#{action}_" : ""
45
- method = "#{action}#{module_name}_#{path_or_url}"
47
+ method = :"#{action}#{module_name}_#{path_or_url}"
46
48
 
47
- class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
48
- def #{method}(resource_or_scope, *args)
49
- scope = Devise::Mapping.find_scope!(resource_or_scope)
50
- _devise_route_context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
51
- end
52
- URL_HELPERS
49
+ define_method method do |resource_or_scope, *args|
50
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
51
+ router_name = Devise.mappings[scope].router_name
52
+ context = router_name ? send(router_name) : _devise_route_context
53
+ context.send("#{action}#{scope}_#{module_name}_#{path_or_url}", *args)
54
+ end
53
55
  end
54
56
  end
55
57
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  # Checks the scope in the given environment and returns the associated failure app.
3
5
  class Delegator
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcrypt'
4
+
5
+ module Devise
6
+ module Encryptor
7
+ def self.digest(klass, password)
8
+ if klass.pepper.present?
9
+ password = "#{password}#{klass.pepper}"
10
+ end
11
+ ::BCrypt::Password.create(password, cost: klass.stretches).to_s
12
+ end
13
+
14
+ def self.compare(klass, hashed_password, password)
15
+ return false if hashed_password.blank?
16
+ bcrypt = ::BCrypt::Password.new(hashed_password)
17
+ if klass.pepper.present?
18
+ password = "#{password}#{klass.pepper}"
19
+ end
20
+ password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
21
+ Devise.secure_compare(password, hashed_password)
22
+ end
23
+ end
24
+ end