devise 2.1.2 → 3.5.10

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 (242) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +39 -10
  3. data/.yardopts +9 -0
  4. data/{CHANGELOG.rdoc → CHANGELOG.md} +445 -112
  5. data/CODE_OF_CONDUCT.md +22 -0
  6. data/CONTRIBUTING.md +16 -0
  7. data/Gemfile +10 -15
  8. data/Gemfile.lock +151 -129
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +256 -96
  11. data/Rakefile +4 -2
  12. data/app/controllers/devise/confirmations_controller.rb +15 -7
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +6 -2
  14. data/app/controllers/devise/passwords_controller.rb +33 -9
  15. data/app/controllers/devise/registrations_controller.rb +66 -26
  16. data/app/controllers/devise/sessions_controller.rb +52 -21
  17. data/app/controllers/devise/unlocks_controller.rb +11 -6
  18. data/app/controllers/devise_controller.rb +65 -58
  19. data/app/helpers/devise_helper.rb +2 -2
  20. data/app/mailers/devise/mailer.rb +19 -10
  21. data/app/views/devise/confirmations/new.html.erb +8 -4
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +2 -2
  23. data/app/views/devise/mailer/password_change.html.erb +3 -0
  24. data/app/views/devise/mailer/reset_password_instructions.html.erb +2 -2
  25. data/app/views/devise/mailer/unlock_instructions.html.erb +2 -2
  26. data/app/views/devise/passwords/edit.html.erb +15 -6
  27. data/app/views/devise/passwords/new.html.erb +8 -4
  28. data/app/views/devise/registrations/edit.html.erb +29 -15
  29. data/app/views/devise/registrations/new.html.erb +19 -8
  30. data/app/views/devise/sessions/new.html.erb +17 -8
  31. data/app/views/devise/shared/{_links.erb → _links.html.erb} +4 -4
  32. data/app/views/devise/unlocks/new.html.erb +8 -4
  33. data/config/locales/en.yml +51 -47
  34. data/devise.gemspec +8 -6
  35. data/devise.png +0 -0
  36. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  37. data/gemfiles/Gemfile.rails-3.2-stable.lock +172 -0
  38. data/gemfiles/Gemfile.rails-4.0-stable +30 -0
  39. data/gemfiles/Gemfile.rails-4.0-stable.lock +166 -0
  40. data/gemfiles/Gemfile.rails-4.1-stable +30 -0
  41. data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
  42. data/gemfiles/Gemfile.rails-4.2-stable +30 -0
  43. data/gemfiles/Gemfile.rails-4.2-stable.lock +193 -0
  44. data/lib/devise/controllers/helpers.rb +126 -108
  45. data/lib/devise/controllers/rememberable.rb +19 -17
  46. data/lib/devise/controllers/scoped_views.rb +1 -1
  47. data/lib/devise/controllers/sign_in_out.rb +96 -0
  48. data/lib/devise/controllers/store_location.rb +58 -0
  49. data/lib/devise/controllers/url_helpers.rb +7 -7
  50. data/lib/devise/encryptor.rb +22 -0
  51. data/lib/devise/failure_app.rb +85 -25
  52. data/lib/devise/hooks/activatable.rb +5 -6
  53. data/lib/devise/hooks/csrf_cleaner.rb +7 -0
  54. data/lib/devise/hooks/forgetable.rb +1 -1
  55. data/lib/devise/hooks/lockable.rb +2 -2
  56. data/lib/devise/hooks/proxy.rb +21 -0
  57. data/lib/devise/hooks/rememberable.rb +5 -4
  58. data/lib/devise/hooks/timeoutable.rb +16 -8
  59. data/lib/devise/hooks/trackable.rb +1 -1
  60. data/lib/devise/mailers/helpers.rb +27 -23
  61. data/lib/devise/mapping.rb +11 -7
  62. data/lib/devise/models/authenticatable.rb +82 -66
  63. data/lib/devise/models/confirmable.rb +142 -55
  64. data/lib/devise/models/database_authenticatable.rb +59 -15
  65. data/lib/devise/models/lockable.rb +41 -30
  66. data/lib/devise/models/omniauthable.rb +3 -3
  67. data/lib/devise/models/recoverable.rb +56 -41
  68. data/lib/devise/models/rememberable.rb +65 -27
  69. data/lib/devise/models/timeoutable.rb +2 -8
  70. data/lib/devise/models/trackable.rb +6 -4
  71. data/lib/devise/models/validatable.rb +9 -9
  72. data/lib/devise/models.rb +4 -13
  73. data/lib/devise/modules.rb +10 -11
  74. data/lib/devise/omniauth/url_helpers.rb +2 -2
  75. data/lib/devise/orm/active_record.rb +1 -1
  76. data/lib/devise/orm/mongoid.rb +1 -1
  77. data/lib/devise/{param_filter.rb → parameter_filter.rb} +10 -11
  78. data/lib/devise/parameter_sanitizer.rb +99 -0
  79. data/lib/devise/rails/routes.rb +173 -115
  80. data/lib/devise/rails/warden_compat.rb +10 -31
  81. data/lib/devise/rails.rb +14 -12
  82. data/lib/devise/strategies/authenticatable.rb +26 -26
  83. data/lib/devise/strategies/base.rb +1 -1
  84. data/lib/devise/strategies/database_authenticatable.rb +8 -4
  85. data/lib/devise/strategies/rememberable.rb +15 -5
  86. data/lib/devise/test_helpers.rb +7 -5
  87. data/lib/devise/time_inflector.rb +14 -0
  88. data/lib/devise/token_generator.rb +70 -0
  89. data/lib/devise/version.rb +1 -1
  90. data/lib/devise.rb +110 -52
  91. data/lib/generators/active_record/devise_generator.rb +34 -18
  92. data/lib/generators/active_record/templates/migration.rb +5 -6
  93. data/lib/generators/active_record/templates/migration_existing.rb +5 -6
  94. data/lib/generators/devise/controllers_generator.rb +44 -0
  95. data/lib/generators/devise/devise_generator.rb +5 -3
  96. data/lib/generators/devise/install_generator.rb +5 -0
  97. data/lib/generators/devise/orm_helpers.rb +25 -6
  98. data/lib/generators/devise/views_generator.rb +52 -22
  99. data/lib/generators/mongoid/devise_generator.rb +21 -26
  100. data/lib/generators/templates/README +9 -5
  101. data/lib/generators/templates/controllers/README +14 -0
  102. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  103. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  104. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  105. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  106. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  107. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  108. data/lib/generators/templates/devise.rb +80 -43
  109. data/lib/generators/templates/markerb/confirmation_instructions.markerb +2 -2
  110. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  111. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  112. data/lib/generators/templates/markerb/unlock_instructions.markerb +2 -2
  113. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +3 -2
  114. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +4 -4
  115. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +2 -2
  116. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -6
  117. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +4 -4
  118. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +6 -6
  119. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +3 -2
  120. data/script/cached-bundle +49 -0
  121. data/script/s3-put +71 -0
  122. data/test/controllers/custom_registrations_controller_test.rb +40 -0
  123. data/test/controllers/helper_methods_test.rb +21 -0
  124. data/test/controllers/helpers_test.rb +95 -32
  125. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  126. data/test/controllers/internal_helpers_test.rb +39 -14
  127. data/test/controllers/load_hooks_controller_test.rb +19 -0
  128. data/test/controllers/passwords_controller_test.rb +31 -0
  129. data/test/controllers/sessions_controller_test.rb +66 -6
  130. data/test/controllers/url_helpers_test.rb +10 -4
  131. data/test/delegator_test.rb +1 -1
  132. data/test/devise_test.rb +45 -10
  133. data/test/failure_app_test.rb +121 -27
  134. data/test/generators/active_record_generator_test.rb +48 -8
  135. data/test/generators/controllers_generator_test.rb +48 -0
  136. data/test/generators/devise_generator_test.rb +2 -2
  137. data/test/generators/mongoid_generator_test.rb +3 -3
  138. data/test/generators/views_generator_test.rb +54 -3
  139. data/test/helpers/devise_helper_test.rb +18 -20
  140. data/test/integration/authenticatable_test.rb +161 -65
  141. data/test/integration/confirmable_test.rb +146 -77
  142. data/test/integration/database_authenticatable_test.rb +43 -30
  143. data/test/integration/http_authenticatable_test.rb +30 -22
  144. data/test/integration/lockable_test.rb +64 -49
  145. data/test/integration/omniauthable_test.rb +17 -15
  146. data/test/integration/recoverable_test.rb +111 -70
  147. data/test/integration/registerable_test.rb +114 -79
  148. data/test/integration/rememberable_test.rb +87 -31
  149. data/test/integration/timeoutable_test.rb +77 -33
  150. data/test/integration/trackable_test.rb +5 -5
  151. data/test/mailers/confirmation_instructions_test.rb +28 -8
  152. data/test/mailers/reset_password_instructions_test.rb +21 -8
  153. data/test/mailers/unlock_instructions_test.rb +20 -6
  154. data/test/mapping_test.rb +12 -5
  155. data/test/models/authenticatable_test.rb +17 -1
  156. data/test/models/confirmable_test.rb +216 -62
  157. data/test/models/database_authenticatable_test.rb +129 -49
  158. data/test/models/lockable_test.rb +132 -45
  159. data/test/models/recoverable_test.rb +100 -54
  160. data/test/models/rememberable_test.rb +89 -94
  161. data/test/models/serializable_test.rb +12 -11
  162. data/test/models/timeoutable_test.rb +6 -1
  163. data/test/models/trackable_test.rb +28 -0
  164. data/test/models/validatable_test.rb +31 -21
  165. data/test/models_test.rb +22 -48
  166. data/test/omniauth/config_test.rb +4 -4
  167. data/test/omniauth/url_helpers_test.rb +7 -4
  168. data/test/orm/active_record.rb +1 -0
  169. data/test/orm/mongoid.rb +2 -3
  170. data/test/parameter_sanitizer_test.rb +81 -0
  171. data/test/rails_app/Rakefile +0 -4
  172. data/test/rails_app/app/active_record/shim.rb +1 -1
  173. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  174. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  175. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  176. data/test/rails_app/app/controllers/admins/sessions_controller.rb +1 -1
  177. data/test/rails_app/app/controllers/admins_controller.rb +0 -5
  178. data/test/rails_app/app/controllers/application_controller.rb +6 -2
  179. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  180. data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
  181. data/test/rails_app/app/controllers/home_controller.rb +1 -1
  182. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +1 -1
  183. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +1 -1
  184. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +4 -4
  185. data/test/rails_app/app/controllers/users_controller.rb +12 -4
  186. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  187. data/test/rails_app/app/mailers/users/mailer.rb +1 -1
  188. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  189. data/test/rails_app/app/mongoid/admin.rb +12 -10
  190. data/test/rails_app/app/mongoid/shim.rb +4 -5
  191. data/test/rails_app/app/mongoid/user.rb +19 -22
  192. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  193. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  194. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  195. data/test/rails_app/app/views/admins/sessions/new.html.erb +1 -1
  196. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -1
  197. data/test/rails_app/app/views/home/index.html.erb +1 -1
  198. data/test/rails_app/app/views/home/join.html.erb +1 -1
  199. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -1
  200. data/test/rails_app/app/views/layouts/application.html.erb +1 -1
  201. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  202. data/test/rails_app/bin/bundle +3 -0
  203. data/test/rails_app/bin/rails +4 -0
  204. data/test/rails_app/bin/rake +4 -0
  205. data/test/rails_app/config/application.rb +4 -5
  206. data/test/rails_app/config/boot.rb +9 -3
  207. data/test/rails_app/config/environment.rb +2 -2
  208. data/test/rails_app/config/environments/development.rb +19 -7
  209. data/test/rails_app/config/environments/production.rb +68 -17
  210. data/test/rails_app/config/environments/test.rb +24 -16
  211. data/test/rails_app/config/initializers/devise.rb +22 -20
  212. data/test/rails_app/config/initializers/secret_token.rb +8 -2
  213. data/test/rails_app/config/initializers/session_store.rb +1 -0
  214. data/test/rails_app/config/routes.rb +71 -46
  215. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +9 -12
  216. data/test/rails_app/db/schema.rb +21 -18
  217. data/test/rails_app/lib/shared_admin.rb +7 -4
  218. data/test/rails_app/lib/shared_user.rb +6 -3
  219. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  220. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  221. data/test/rails_test.rb +9 -0
  222. data/test/routes_test.rb +94 -78
  223. data/test/support/action_controller/record_identifier.rb +10 -0
  224. data/test/support/assertions.rb +2 -3
  225. data/test/support/helpers.rb +18 -32
  226. data/test/support/integration.rb +17 -16
  227. data/test/support/locale/en.yml +4 -0
  228. data/test/support/mongoid.yml +6 -0
  229. data/test/test_helper.rb +8 -1
  230. data/test/test_helpers_test.rb +64 -20
  231. data/test/test_models.rb +33 -0
  232. data/test/time_helpers.rb +137 -0
  233. metadata +172 -51
  234. data/app/views/devise/_links.erb +0 -3
  235. data/gemfiles/Gemfile.rails-3.1.x +0 -35
  236. data/gemfiles/Gemfile.rails-3.1.x.lock +0 -167
  237. data/lib/devise/models/token_authenticatable.rb +0 -77
  238. data/lib/devise/strategies/token_authenticatable.rb +0 -56
  239. data/test/indifferent_hash.rb +0 -33
  240. data/test/integration/token_authenticatable_test.rb +0 -161
  241. data/test/models/token_authenticatable_test.rb +0 -55
  242. data/test/rails_app/script/rails +0 -10
@@ -3,12 +3,80 @@ module Devise
3
3
  # Those helpers are convenience methods added to ApplicationController.
4
4
  module Helpers
5
5
  extend ActiveSupport::Concern
6
+ include Devise::Controllers::SignInOut
7
+ include Devise::Controllers::StoreLocation
6
8
 
7
9
  included do
8
- helper_method :warden, :signed_in?, :devise_controller?
10
+ if respond_to?(:helper_method)
11
+ helper_method :warden, :signed_in?, :devise_controller?
12
+ end
9
13
  end
10
14
 
11
15
  module ClassMethods
16
+ # Define authentication filters and accessor helpers for a group of mappings.
17
+ # These methods are useful when you are working with multiple mappings that
18
+ # share some functionality. They are pretty much the same as the ones
19
+ # defined for normal mappings.
20
+ #
21
+ # Example:
22
+ #
23
+ # inside BlogsController (or any other controller, it doesn't matter which):
24
+ # devise_group :blogger, contains: [:user, :admin]
25
+ #
26
+ # Generated methods:
27
+ # authenticate_blogger! # Redirects unless user or admin are signed in
28
+ # blogger_signed_in? # Checks whether there is either a user or an admin signed in
29
+ # current_blogger # Currently signed in user or admin
30
+ # current_bloggers # Currently signed in user and admin
31
+ #
32
+ # Use:
33
+ # before_filter :authenticate_blogger! # Redirects unless either a user or an admin are authenticated
34
+ # before_filter ->{ authenticate_blogger! :admin } # Redirects to the admin login page
35
+ # current_blogger :user # Preferably returns a User if one is signed in
36
+ #
37
+ def devise_group(group_name, opts={})
38
+ mappings = "[#{ opts[:contains].map { |m| ":#{m}" }.join(',') }]"
39
+
40
+ class_eval <<-METHODS, __FILE__, __LINE__ + 1
41
+ def authenticate_#{group_name}!(favourite=nil, opts={})
42
+ unless #{group_name}_signed_in?
43
+ mappings = #{mappings}
44
+ mappings.unshift mappings.delete(favourite.to_sym) if favourite
45
+ mappings.each do |mapping|
46
+ opts[:scope] = mapping
47
+ warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
48
+ end
49
+ end
50
+ end
51
+
52
+ def #{group_name}_signed_in?
53
+ #{mappings}.any? do |mapping|
54
+ warden.authenticate?(scope: mapping)
55
+ end
56
+ end
57
+
58
+ def current_#{group_name}(favourite=nil)
59
+ mappings = #{mappings}
60
+ mappings.unshift mappings.delete(favourite.to_sym) if favourite
61
+ mappings.each do |mapping|
62
+ current = warden.authenticate(scope: mapping)
63
+ return current if current
64
+ end
65
+ nil
66
+ end
67
+
68
+ def current_#{group_name.to_s.pluralize}
69
+ #{mappings}.map do |mapping|
70
+ warden.authenticate(scope: mapping)
71
+ end.compact
72
+ end
73
+
74
+ if respond_to?(:helper_method)
75
+ helper_method "current_#{group_name}", "current_#{group_name.to_s.pluralize}", "#{group_name}_signed_in?"
76
+ end
77
+ METHODS
78
+ end
79
+
12
80
  def log_process_action(payload)
13
81
  payload[:status] ||= 401 unless payload[:exception]
14
82
  super
@@ -53,7 +121,7 @@ module Devise
53
121
  end
54
122
 
55
123
  def current_#{mapping}
56
- @current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
124
+ @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
57
125
  end
58
126
 
59
127
  def #{mapping}_session
@@ -62,7 +130,9 @@ module Devise
62
130
  METHODS
63
131
 
64
132
  ActiveSupport.on_load(:action_controller) do
65
- helper_method "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session"
133
+ if respond_to?(:helper_method)
134
+ helper_method "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session"
135
+ end
66
136
  end
67
137
  end
68
138
 
@@ -75,112 +145,41 @@ module Devise
75
145
  # the controllers defined inside devise. Useful if you want to apply a before
76
146
  # filter to all controllers, except the ones in devise:
77
147
  #
78
- # before_filter :my_filter, :unless => :devise_controller?
148
+ # before_filter :my_filter, unless: :devise_controller?
79
149
  def devise_controller?
80
- is_a?(DeviseController)
81
- end
82
-
83
- # Tell warden that params authentication is allowed for that specific page.
84
- def allow_params_authentication!
85
- request.env["devise.allow_params_authentication"] = true
86
- end
87
-
88
- # Return true if the given scope is signed in session. If no scope given, return
89
- # true if any scope is signed in. Does not run authentication hooks.
90
- def signed_in?(scope=nil)
91
- [ scope || Devise.mappings.keys ].flatten.any? do |_scope|
92
- warden.authenticate?(:scope => _scope)
93
- end
150
+ is_a?(::DeviseController)
94
151
  end
95
152
 
96
- # Sign in a user that already was authenticated. This helper is useful for logging
97
- # users in after sign up.
98
- #
99
- # All options given to sign_in is passed forward to the set_user method in warden.
100
- # The only exception is the :bypass option, which bypass warden callbacks and stores
101
- # the user straight in session. This option is useful in cases the user is already
102
- # signed in, but we want to refresh the credentials in session.
103
- #
104
- # Examples:
105
- #
106
- # sign_in :user, @user # sign_in(scope, resource)
107
- # sign_in @user # sign_in(resource)
108
- # sign_in @user, :event => :authentication # sign_in(resource, options)
109
- # sign_in @user, :bypass => true # sign_in(resource, options)
110
- #
111
- def sign_in(resource_or_scope, *args)
112
- options = args.extract_options!
113
- scope = Devise::Mapping.find_scope!(resource_or_scope)
114
- resource = args.last || resource_or_scope
115
-
116
- expire_session_data_after_sign_in!
117
-
118
- if options[:bypass]
119
- warden.session_serializer.store(resource, scope)
120
- elsif warden.user(scope) == resource && !options.delete(:force)
121
- # Do nothing. User already signed in and we are not forcing it.
122
- true
153
+ # Setup a param sanitizer to filter parameters using strong_parameters. See
154
+ # lib/devise/parameter_sanitizer.rb for more info. Override this
155
+ # method in your application controller to use your own parameter sanitizer.
156
+ def devise_parameter_sanitizer
157
+ @devise_parameter_sanitizer ||= if defined?(ActionController::StrongParameters)
158
+ Devise::ParameterSanitizer.new(resource_class, resource_name, params)
123
159
  else
124
- warden.set_user(resource, options.merge!(:scope => scope))
160
+ Devise::BaseSanitizer.new(resource_class, resource_name, params)
125
161
  end
126
162
  end
127
163
 
128
- # Sign out a given user or scope. This helper is useful for signing out a user
129
- # after deleting accounts. Returns true if there was a logout and false if there
130
- # is no user logged in on the referred scope
131
- #
132
- # Examples:
133
- #
134
- # sign_out :user # sign_out(scope)
135
- # sign_out @user # sign_out(resource)
136
- #
137
- def sign_out(resource_or_scope=nil)
138
- return sign_out_all_scopes unless resource_or_scope
139
- scope = Devise::Mapping.find_scope!(resource_or_scope)
140
- user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
141
-
142
- warden.raw_session.inspect # Without this inspect here. The session does not clear.
143
- warden.logout(scope)
144
- warden.clear_strategies_cache!(:scope => scope)
145
- instance_variable_set(:"@current_#{scope}", nil)
146
-
147
- !!user
148
- end
149
-
150
- # Sign out all active users or scopes. This helper is useful for signing out all roles
151
- # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
152
- # and false if there was no user logged in on all scopes.
153
- def sign_out_all_scopes(lock=true)
154
- users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
155
-
156
- warden.raw_session.inspect
157
- warden.logout
158
- expire_devise_cached_variables!
159
- warden.clear_strategies_cache!
160
- warden.lock! if lock
161
-
162
- users.any?
163
- end
164
-
165
- # Returns and delete the url stored in the session for the given scope. Useful
166
- # for giving redirect backs after sign up:
167
- #
168
- # Example:
169
- #
170
- # redirect_to stored_location_for(:user) || root_path
171
- #
172
- def stored_location_for(resource_or_scope)
173
- scope = Devise::Mapping.find_scope!(resource_or_scope)
174
- session.delete("#{scope}_return_to")
164
+ # Tell warden that params authentication is allowed for that specific page.
165
+ def allow_params_authentication!
166
+ request.env["devise.allow_params_authentication"] = true
175
167
  end
176
168
 
177
- # The scope root url to be used when he's signed in. By default, it first
169
+ # The scope root url to be used when they're signed in. By default, it first
178
170
  # tries to find a resource_root_path, otherwise it uses the root_path.
179
171
  def signed_in_root_path(resource_or_scope)
180
172
  scope = Devise::Mapping.find_scope!(resource_or_scope)
173
+ router_name = Devise.mappings[scope].router_name
174
+
181
175
  home_path = "#{scope}_root_path"
182
- if respond_to?(home_path, true)
183
- send(home_path)
176
+
177
+ context = router_name ? send(router_name) : self
178
+
179
+ if context.respond_to?(home_path, true)
180
+ context.send(home_path)
181
+ elsif context.respond_to?(:root_path)
182
+ context.root_path
184
183
  elsif respond_to?(:root_path)
185
184
  root_path
186
185
  else
@@ -197,10 +196,10 @@ module Devise
197
196
  # root path. For a user scope, you can define the default url in
198
197
  # the following way:
199
198
  #
200
- # map.user_root '/users', :controller => 'users' # creates user_root_path
199
+ # get '/users' => 'users#index', as: :user_root # creates user_root_path
201
200
  #
202
- # map.namespace :user do |user|
203
- # user.root :controller => 'users' # creates user_root_path
201
+ # namespace :user do
202
+ # root 'users#index' # creates user_root_path
204
203
  # end
205
204
  #
206
205
  # If the resource root path is not defined, root_path is used. However,
@@ -226,7 +225,10 @@ module Devise
226
225
  #
227
226
  # By default it is the root_path.
228
227
  def after_sign_out_path_for(resource_or_scope)
229
- respond_to?(:root_path) ? root_path : "/"
228
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
229
+ router_name = Devise.mappings[scope].router_name
230
+ context = router_name ? send(router_name) : self
231
+ context.respond_to?(:root_path) ? context.root_path : "/"
230
232
  end
231
233
 
232
234
  # Sign in a user and tries to redirect first to the stored location and
@@ -240,10 +242,6 @@ module Devise
240
242
  redirect_to after_sign_in_path_for(resource)
241
243
  end
242
244
 
243
- def expire_session_data_after_sign_in!
244
- session.keys.grep(/^devise\./).each { |k| session.delete(k) }
245
- end
246
-
247
245
  # Sign out a user and tries to redirect to the url specified by
248
246
  # after_sign_out_path_for.
249
247
  def sign_out_and_redirect(resource_or_scope)
@@ -256,16 +254,36 @@ module Devise
256
254
  # Overwrite Rails' handle unverified request to sign out all scopes,
257
255
  # clear run strategies and remove cached variables.
258
256
  def handle_unverified_request
259
- sign_out_all_scopes(false)
257
+ super # call the default behaviour which resets/nullifies/raises
260
258
  request.env["devise.skip_storage"] = true
261
- expire_devise_cached_variables!
262
- super # call the default behaviour which resets the session
259
+ sign_out_all_scopes(false)
260
+ end
261
+
262
+ def request_format
263
+ @request_format ||= request.format.try(:ref)
264
+ end
265
+
266
+ def is_navigational_format?
267
+ Devise.navigational_formats.include?(request_format)
268
+ end
269
+
270
+ # Check if flash messages should be emitted. Default is to do it on
271
+ # navigational formats
272
+ def is_flashing_format?
273
+ is_navigational_format?
263
274
  end
264
275
 
265
276
  private
266
277
 
267
- def expire_devise_cached_variables!
278
+ def expire_session_data_after_sign_in!
279
+ ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated " \
280
+ "in favor of expire_data_after_sign_in!"
281
+ expire_data_after_sign_in!
282
+ end
283
+
284
+ def expire_data_after_sign_out!
268
285
  Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
286
+ super
269
287
  end
270
288
  end
271
289
  end
@@ -1,36 +1,34 @@
1
1
  module Devise
2
2
  module Controllers
3
3
  # A module that may be optionally included in a controller in order
4
- # to provide remember me behavior.
4
+ # to provide remember me behavior. Useful when signing in is done
5
+ # through a callback, like in OmniAuth.
5
6
  module Rememberable
6
7
  # Return default cookie values retrieved from session options.
7
8
  def self.cookie_values
8
9
  Rails.configuration.session_options.slice(:path, :domain, :secure)
9
10
  end
10
11
 
11
- # A small warden proxy so we can remember and forget uses from hooks.
12
- class Proxy #:nodoc:
13
- include Devise::Controllers::Rememberable
14
-
15
- delegate :cookies, :env, :to => :@warden
16
-
17
- def initialize(warden)
18
- @warden = warden
19
- end
12
+ def remember_me_is_active?(resource)
13
+ return false unless resource.respond_to?(:remember_me)
14
+ scope = Devise::Mapping.find_scope!(resource)
15
+ _, token, generated_at = cookies.signed[remember_key(resource, scope)]
16
+ resource.remember_me?(token, generated_at)
20
17
  end
21
18
 
22
19
  # Remembers the given resource by setting up a cookie
23
20
  def remember_me(resource)
21
+ return if env["devise.skip_storage"]
24
22
  scope = Devise::Mapping.find_scope!(resource)
25
- resource.remember_me!(resource.extend_remember_period)
26
- cookies.signed["remember_#{scope}_token"] = remember_cookie_values(resource)
23
+ resource.remember_me!
24
+ cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource)
27
25
  end
28
26
 
29
27
  # Forgets the given resource by deleting a cookie
30
28
  def forget_me(resource)
31
29
  scope = Devise::Mapping.find_scope!(resource)
32
30
  resource.forget_me!
33
- cookies.delete("remember_#{scope}_token", forget_cookie_values(resource))
31
+ cookies.delete(remember_key(resource, scope), forget_cookie_values(resource))
34
32
  end
35
33
 
36
34
  protected
@@ -40,13 +38,17 @@ module Devise
40
38
  end
41
39
 
42
40
  def remember_cookie_values(resource)
43
- options = { :httponly => true }
41
+ options = { httponly: true }
44
42
  options.merge!(forget_cookie_values(resource))
45
43
  options.merge!(
46
- :value => resource.class.serialize_into_cookie(resource),
47
- :expires => resource.remember_expires_at
44
+ value: resource.class.serialize_into_cookie(resource),
45
+ expires: resource.remember_expires_at
48
46
  )
49
47
  end
48
+
49
+ def remember_key(resource, scope)
50
+ resource.rememberable_options.fetch(:key, "remember_#{scope}_token")
51
+ end
50
52
  end
51
53
  end
52
- end
54
+ end
@@ -14,4 +14,4 @@ module Devise
14
14
  end
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -0,0 +1,96 @@
1
+ module Devise
2
+ module Controllers
3
+ # Provide sign in and sign out functionality.
4
+ # Included by default in all controllers.
5
+ module SignInOut
6
+ # 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.
8
+ def signed_in?(scope=nil)
9
+ [scope || Devise.mappings.keys].flatten.any? do |_scope|
10
+ warden.authenticate?(scope: _scope)
11
+ end
12
+ end
13
+
14
+ # 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.
21
+ #
22
+ # Examples:
23
+ #
24
+ # sign_in :user, @user # sign_in(scope, resource)
25
+ # 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)
29
+ #
30
+ def sign_in(resource_or_scope, *args)
31
+ options = args.extract_options!
32
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
33
+ resource = args.last || resource_or_scope
34
+
35
+ expire_data_after_sign_in!
36
+
37
+ if options[:bypass]
38
+ warden.session_serializer.store(resource, scope)
39
+ elsif warden.user(scope) == resource && !options.delete(:force)
40
+ # Do nothing. User already signed in and we are not forcing it.
41
+ true
42
+ else
43
+ warden.set_user(resource, options.merge!(scope: scope))
44
+ end
45
+ end
46
+
47
+ # Sign out a given user or scope. This helper is useful for signing out a user
48
+ # after deleting accounts. Returns true if there was a logout and false if there
49
+ # is no user logged in on the referred scope
50
+ #
51
+ # Examples:
52
+ #
53
+ # sign_out :user # sign_out(scope)
54
+ # sign_out @user # sign_out(resource)
55
+ #
56
+ def sign_out(resource_or_scope=nil)
57
+ return sign_out_all_scopes unless resource_or_scope
58
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
59
+ user = warden.user(scope: scope, run_callbacks: false) # If there is no user
60
+
61
+ warden.raw_session.inspect # Without this inspect here. The session does not clear.
62
+ warden.logout(scope)
63
+ warden.clear_strategies_cache!(scope: scope)
64
+ instance_variable_set(:"@current_#{scope}", nil)
65
+
66
+ !!user
67
+ end
68
+
69
+ # Sign out all active users or scopes. This helper is useful for signing out all roles
70
+ # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
71
+ # and false if there was no user logged in on all scopes.
72
+ def sign_out_all_scopes(lock=true)
73
+ users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
74
+
75
+ warden.logout
76
+ expire_data_after_sign_out!
77
+ warden.clear_strategies_cache!
78
+ warden.lock! if lock
79
+
80
+ users.any?
81
+ end
82
+
83
+ private
84
+
85
+ def expire_data_after_sign_in!
86
+ # session.keys will return an empty array if the session is not yet loaded.
87
+ # This is a bug in both Rack and Rails.
88
+ # A call to #empty? forces the session to be loaded.
89
+ session.empty?
90
+ session.keys.grep(/^devise\./).each { |k| session.delete(k) }
91
+ end
92
+
93
+ alias :expire_data_after_sign_out! :expire_data_after_sign_in!
94
+ end
95
+ end
96
+ end