devise 3.2.0 → 4.7.1

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 (235) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +260 -949
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +383 -100
  5. data/app/controllers/devise/confirmations_controller.rb +13 -5
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +12 -6
  7. data/app/controllers/devise/passwords_controller.rb +23 -8
  8. data/app/controllers/devise/registrations_controller.rb +60 -24
  9. data/app/controllers/devise/sessions_controller.rb +48 -16
  10. data/app/controllers/devise/unlocks_controller.rb +11 -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 +113 -49
  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 +76 -0
  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 +122 -40
  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 +81 -56
  49. data/lib/devise/models/confirmable.rb +137 -42
  50. data/lib/devise/models/database_authenticatable.rb +114 -28
  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 +150 -104
  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 +21 -10
  73. data/lib/devise/strategies/base.rb +3 -1
  74. data/lib/devise/strategies/database_authenticatable.rb +15 -4
  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 -83
  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 +9 -5
  88. data/lib/generators/devise/install_generator.rb +22 -0
  89. data/lib/generators/devise/orm_helpers.rb +10 -21
  90. data/lib/generators/devise/views_generator.rb +51 -28
  91. data/lib/generators/mongoid/devise_generator.rb +22 -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 +12 -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 +46 -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 -253
  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 -178
  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 -244
  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 -8
  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 -34
  210. data/test/rails_app/config/environments/production.rb +0 -84
  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 -51
  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 -34
  234. data/test/test_helpers_test.rb +0 -173
  235. data/test/test_models.rb +0 -26
@@ -1,15 +1,84 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Controllers
3
5
  # Those helpers are convenience methods added to ApplicationController.
4
6
  module Helpers
5
7
  extend ActiveSupport::Concern
6
8
  include Devise::Controllers::SignInOut
9
+ include Devise::Controllers::StoreLocation
7
10
 
8
11
  included do
9
- helper_method :warden, :signed_in?, :devise_controller?
12
+ if respond_to?(:helper_method)
13
+ helper_method :warden, :signed_in?, :devise_controller?
14
+ end
10
15
  end
11
16
 
12
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
+
13
82
  def log_process_action(payload)
14
83
  payload[:status] ||= 401 unless payload[:exception]
15
84
  super
@@ -17,7 +86,7 @@ module Devise
17
86
  end
18
87
 
19
88
  # Define authentication filters and accessor helpers based on mappings.
20
- # These filters should be used inside the controllers as before_filters,
89
+ # These filters should be used inside the controllers as before_actions,
21
90
  # so you can control the scope of the user who should be signed in to
22
91
  # access that specific controller/action.
23
92
  # Example:
@@ -37,8 +106,8 @@ module Devise
37
106
  # admin_session # Session data available only to the admin scope
38
107
  #
39
108
  # Use:
40
- # before_filter :authenticate_user! # Tell devise to use :user map
41
- # 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
42
111
  #
43
112
  def self.define_helpers(mapping) #:nodoc:
44
113
  mapping = mapping.name
@@ -54,7 +123,7 @@ module Devise
54
123
  end
55
124
 
56
125
  def current_#{mapping}
57
- @current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
126
+ @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
58
127
  end
59
128
 
60
129
  def #{mapping}_session
@@ -63,33 +132,31 @@ module Devise
63
132
  METHODS
64
133
 
65
134
  ActiveSupport.on_load(:action_controller) do
66
- 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
67
138
  end
68
139
  end
69
140
 
70
141
  # The main accessor for the warden proxy instance
71
142
  def warden
72
- request.env['warden']
143
+ request.env['warden'] or raise MissingWarden
73
144
  end
74
145
 
75
146
  # Return true if it's a devise_controller. false to all controllers unless
76
147
  # the controllers defined inside devise. Useful if you want to apply a before
77
148
  # filter to all controllers, except the ones in devise:
78
149
  #
79
- # before_filter :my_filter, :unless => :devise_controller?
150
+ # before_action :my_filter, unless: :devise_controller?
80
151
  def devise_controller?
81
- is_a?(DeviseController)
152
+ is_a?(::DeviseController)
82
153
  end
83
154
 
84
- # Setup a param sanitizer to filter parameters using strong_parameters. See
155
+ # Set up a param sanitizer to filter parameters using strong_parameters. See
85
156
  # lib/devise/parameter_sanitizer.rb for more info. Override this
86
157
  # method in your application controller to use your own parameter sanitizer.
87
158
  def devise_parameter_sanitizer
88
- @devise_parameter_sanitizer ||= if defined?(ActionController::StrongParameters)
89
- Devise::ParameterSanitizer.new(resource_class, resource_name, params)
90
- else
91
- Devise::BaseSanitizer.new(resource_class, resource_name, params)
92
- end
159
+ @devise_parameter_sanitizer ||= Devise::ParameterSanitizer.new(resource_class, resource_name, params)
93
160
  end
94
161
 
95
162
  # Tell warden that params authentication is allowed for that specific page.
@@ -97,30 +164,20 @@ module Devise
97
164
  request.env["devise.allow_params_authentication"] = true
98
165
  end
99
166
 
100
- # Returns and delete (if it's navigational format) the url stored in the session for
101
- # the given scope. Useful for giving redirect backs after sign up:
102
- #
103
- # Example:
104
- #
105
- # redirect_to stored_location_for(:user) || root_path
106
- #
107
- def stored_location_for(resource_or_scope)
108
- scope = Devise::Mapping.find_scope!(resource_or_scope)
109
-
110
- if is_navigational_format?
111
- session.delete("#{scope}_return_to")
112
- else
113
- session["#{scope}_return_to"]
114
- end
115
- end
116
-
117
- # 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
118
168
  # tries to find a resource_root_path, otherwise it uses the root_path.
119
169
  def signed_in_root_path(resource_or_scope)
120
170
  scope = Devise::Mapping.find_scope!(resource_or_scope)
171
+ router_name = Devise.mappings[scope].router_name
172
+
121
173
  home_path = "#{scope}_root_path"
122
- if respond_to?(home_path, true)
123
- 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
124
181
  elsif respond_to?(:root_path)
125
182
  root_path
126
183
  else
@@ -137,10 +194,10 @@ module Devise
137
194
  # root path. For a user scope, you can define the default url in
138
195
  # the following way:
139
196
  #
140
- # map.user_root '/users', :controller => 'users' # creates user_root_path
197
+ # get '/users' => 'users#index', as: :user_root # creates user_root_path
141
198
  #
142
- # map.namespace :user do |user|
143
- # user.root :controller => 'users' # creates user_root_path
199
+ # namespace :user do
200
+ # root 'users#index' # creates user_root_path
144
201
  # end
145
202
  #
146
203
  # If the resource root path is not defined, root_path is used. However,
@@ -166,7 +223,10 @@ module Devise
166
223
  #
167
224
  # By default it is the root_path.
168
225
  def after_sign_out_path_for(resource_or_scope)
169
- 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 : "/"
170
230
  end
171
231
 
172
232
  # Sign in a user and tries to redirect first to the stored location and
@@ -192,10 +252,9 @@ module Devise
192
252
  # Overwrite Rails' handle unverified request to sign out all scopes,
193
253
  # clear run strategies and remove cached variables.
194
254
  def handle_unverified_request
195
- sign_out_all_scopes(false)
255
+ super # call the default behaviour which resets/nullifies/raises
196
256
  request.env["devise.skip_storage"] = true
197
- expire_data_after_sign_out!
198
- super # call the default behaviour which resets the session
257
+ sign_out_all_scopes(false)
199
258
  end
200
259
 
201
260
  def request_format
@@ -209,21 +268,26 @@ module Devise
209
268
  # Check if flash messages should be emitted. Default is to do it on
210
269
  # navigational formats
211
270
  def is_flashing_format?
212
- is_navigational_format?
271
+ request.respond_to?(:flash) && is_navigational_format?
213
272
  end
214
273
 
215
274
  private
216
275
 
217
- def expire_session_data_after_sign_in!
218
- ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated " \
219
- "in favor of expire_data_after_sign_in!"
220
- expire_data_after_sign_in!
221
- end
222
-
223
276
  def expire_data_after_sign_out!
224
277
  Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
225
278
  super
226
279
  end
227
280
  end
228
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
229
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
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module Devise
6
+ module Controllers
7
+ # Provide the ability to store a location.
8
+ # Used to redirect back to a desired path after sign in.
9
+ # Included by default in all controllers.
10
+ module StoreLocation
11
+ # Returns and delete (if it's navigational format) the url stored in the session for
12
+ # the given scope. Useful for giving redirect backs after sign up:
13
+ #
14
+ # Example:
15
+ #
16
+ # redirect_to stored_location_for(:user) || root_path
17
+ #
18
+ def stored_location_for(resource_or_scope)
19
+ session_key = stored_location_key_for(resource_or_scope)
20
+
21
+ if is_navigational_format?
22
+ session.delete(session_key)
23
+ else
24
+ session[session_key]
25
+ end
26
+ end
27
+
28
+ # Stores the provided location to redirect the user after signing in.
29
+ # Useful in combination with the `stored_location_for` helper.
30
+ #
31
+ # Example:
32
+ #
33
+ # store_location_for(:user, dashboard_path)
34
+ # redirect_to user_facebook_omniauth_authorize_path
35
+ #
36
+ def store_location_for(resource_or_scope, location)
37
+ session_key = stored_location_key_for(resource_or_scope)
38
+
39
+ path = extract_path_from_location(location)
40
+ session[session_key] = path if path
41
+ end
42
+
43
+ private
44
+
45
+ def parse_uri(location)
46
+ location && URI.parse(location)
47
+ rescue URI::InvalidURIError
48
+ nil
49
+ end
50
+
51
+ def stored_location_key_for(resource_or_scope)
52
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
53
+ "#{scope}_return_to"
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
74
+ end
75
+ end
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