devise 3.1.2 → 3.2.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 (62) hide show
  1. data/CHANGELOG.md +111 -99
  2. data/Gemfile.lock +1 -1
  3. data/README.md +2 -2
  4. data/app/controllers/devise/confirmations_controller.rb +2 -9
  5. data/app/controllers/devise/passwords_controller.rb +1 -1
  6. data/app/controllers/devise/registrations_controller.rb +6 -6
  7. data/app/controllers/devise/sessions_controller.rb +3 -3
  8. data/app/controllers/devise/unlocks_controller.rb +1 -1
  9. data/app/controllers/devise_controller.rb +6 -2
  10. data/app/mailers/devise/mailer.rb +15 -13
  11. data/config/locales/en.yml +1 -2
  12. data/gemfiles/Gemfile.rails-3.2.x.lock +1 -1
  13. data/lib/devise.rb +23 -12
  14. data/lib/devise/controllers/helpers.rb +16 -84
  15. data/lib/devise/controllers/rememberable.rb +2 -12
  16. data/lib/devise/controllers/sign_in_out.rb +103 -0
  17. data/lib/devise/failure_app.rb +11 -2
  18. data/lib/devise/hooks/forgetable.rb +1 -1
  19. data/lib/devise/hooks/proxy.rb +21 -0
  20. data/lib/devise/hooks/rememberable.rb +1 -1
  21. data/lib/devise/hooks/timeoutable.rb +4 -1
  22. data/lib/devise/models.rb +0 -5
  23. data/lib/devise/models/authenticatable.rb +8 -9
  24. data/lib/devise/models/confirmable.rb +0 -4
  25. data/lib/devise/models/database_authenticatable.rb +17 -7
  26. data/lib/devise/models/lockable.rb +6 -4
  27. data/lib/devise/models/recoverable.rb +0 -8
  28. data/lib/devise/modules.rb +0 -1
  29. data/lib/devise/rails/routes.rb +29 -15
  30. data/lib/devise/strategies/database_authenticatable.rb +3 -6
  31. data/lib/devise/test_helpers.rb +1 -0
  32. data/lib/devise/version.rb +1 -1
  33. data/lib/generators/mongoid/devise_generator.rb +0 -3
  34. data/lib/generators/templates/devise.rb +6 -10
  35. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  36. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  37. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  38. data/test/controllers/internal_helpers_test.rb +2 -2
  39. data/test/controllers/sessions_controller_test.rb +1 -1
  40. data/test/devise_test.rb +12 -1
  41. data/test/failure_app_test.rb +11 -0
  42. data/test/integration/confirmable_test.rb +0 -12
  43. data/test/integration/http_authenticatable_test.rb +0 -10
  44. data/test/integration/recoverable_test.rb +2 -2
  45. data/test/integration/rememberable_test.rb +3 -3
  46. data/test/integration/timeoutable_test.rb +28 -0
  47. data/test/mapping_test.rb +2 -2
  48. data/test/models/confirmable_test.rb +0 -9
  49. data/test/models/database_authenticatable_test.rb +19 -1
  50. data/test/models/lockable_test.rb +16 -10
  51. data/test/models/recoverable_test.rb +0 -10
  52. data/test/rails_app/app/mongoid/user.rb +0 -3
  53. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -3
  54. data/test/rails_app/db/schema.rb +0 -1
  55. data/test/rails_app/lib/shared_user.rb +1 -1
  56. data/test/support/locale/en.yml +4 -0
  57. data/test/test_helpers_test.rb +22 -0
  58. metadata +4 -8
  59. data/lib/devise/models/token_authenticatable.rb +0 -92
  60. data/lib/devise/strategies/token_authenticatable.rb +0 -91
  61. data/test/integration/token_authenticatable_test.rb +0 -205
  62. data/test/models/token_authenticatable_test.rb +0 -55
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- devise (3.1.2)
15
+ devise (3.2.0)
16
16
  bcrypt-ruby (~> 3.0)
17
17
  orm_adapter (~> 0.1)
18
18
  railties (>= 3.2.6, < 5)
data/README.md CHANGED
@@ -35,7 +35,7 @@ Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby i
35
35
 
36
36
  The Devise Wiki has lots of additional information about Devise including many "how-to" articles and answers to the most frequently asked questions. Please browse the Wiki after finishing this README:
37
37
 
38
- https://wiki.github.com/plataformatec/devise
38
+ https://github.com/plataformatec/devise/wiki
39
39
 
40
40
  ### Bug reports
41
41
 
@@ -445,7 +445,7 @@ https://github.com/hassox/warden
445
445
 
446
446
  We have a long list of valued contributors. Check them all at:
447
447
 
448
- https://github.com/plataformatec/devise/contributors
448
+ https://github.com/plataformatec/devise/graphs/contributors
449
449
 
450
450
  ## License
451
451
 
@@ -20,12 +20,7 @@ class Devise::ConfirmationsController < DeviseController
20
20
  self.resource = resource_class.confirm_by_token(params[:confirmation_token])
21
21
 
22
22
  if resource.errors.empty?
23
- if Devise.allow_insecure_sign_in_after_confirmation
24
- set_flash_message(:notice, :confirmed_and_signed_in) if is_navigational_format?
25
- sign_in(resource_name, resource)
26
- else
27
- set_flash_message(:notice, :confirmed) if is_navigational_format?
28
- end
23
+ set_flash_message(:notice, :confirmed) if is_flashing_format?
29
24
  respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
30
25
  else
31
26
  respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
@@ -41,9 +36,7 @@ class Devise::ConfirmationsController < DeviseController
41
36
 
42
37
  # The path used after confirmation.
43
38
  def after_confirmation_path_for(resource_name, resource)
44
- if Devise.allow_insecure_sign_in_after_confirmation
45
- after_sign_in_path_for(resource)
46
- elsif signed_in?
39
+ if signed_in?
47
40
  signed_in_root_path(resource)
48
41
  else
49
42
  new_session_path(resource_name)
@@ -32,7 +32,7 @@ class Devise::PasswordsController < DeviseController
32
32
  if resource.errors.empty?
33
33
  resource.unlock_access! if unlockable?(resource)
34
34
  flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
35
- set_flash_message(:notice, flash_message) if is_navigational_format?
35
+ set_flash_message(:notice, flash_message) if is_flashing_format?
36
36
  sign_in(resource_name, resource)
37
37
  respond_with resource, :location => after_resetting_password_path_for(resource)
38
38
  else
@@ -14,12 +14,12 @@ class Devise::RegistrationsController < DeviseController
14
14
 
15
15
  if resource.save
16
16
  if resource.active_for_authentication?
17
- set_flash_message :notice, :signed_up if is_navigational_format?
17
+ set_flash_message :notice, :signed_up if is_flashing_format?
18
18
  sign_up(resource_name, resource)
19
19
  respond_with resource, :location => after_sign_up_path_for(resource)
20
20
  else
21
- set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
22
- expire_session_data_after_sign_in!
21
+ set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
22
+ expire_data_after_sign_in!
23
23
  respond_with resource, :location => after_inactive_sign_up_path_for(resource)
24
24
  end
25
25
  else
@@ -41,7 +41,7 @@ class Devise::RegistrationsController < DeviseController
41
41
  prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
42
42
 
43
43
  if update_resource(resource, account_update_params)
44
- if is_navigational_format?
44
+ if is_flashing_format?
45
45
  flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
46
46
  :update_needs_confirmation : :updated
47
47
  set_flash_message :notice, flash_key
@@ -58,7 +58,7 @@ class Devise::RegistrationsController < DeviseController
58
58
  def destroy
59
59
  resource.destroy
60
60
  Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
61
- set_flash_message :notice, :destroyed if is_navigational_format?
61
+ set_flash_message :notice, :destroyed if is_flashing_format?
62
62
  respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
63
63
  end
64
64
 
@@ -68,7 +68,7 @@ class Devise::RegistrationsController < DeviseController
68
68
  # cancel oauth signing in/up in the middle of the process,
69
69
  # removing all OAuth session data.
70
70
  def cancel
71
- expire_session_data_after_sign_in!
71
+ expire_data_after_sign_in!
72
72
  redirect_to new_registration_path(resource_name)
73
73
  end
74
74
 
@@ -1,7 +1,7 @@
1
1
  class Devise::SessionsController < DeviseController
2
2
  prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
3
3
  prepend_before_filter :allow_params_authentication!, :only => :create
4
- prepend_before_filter { request.env["devise.skip_timeout"] = true }
4
+ prepend_before_filter :only => [ :create, :destroy ] { request.env["devise.skip_timeout"] = true }
5
5
 
6
6
  # GET /resource/sign_in
7
7
  def new
@@ -13,7 +13,7 @@ class Devise::SessionsController < DeviseController
13
13
  # POST /resource/sign_in
14
14
  def create
15
15
  self.resource = warden.authenticate!(auth_options)
16
- set_flash_message(:notice, :signed_in) if is_navigational_format?
16
+ set_flash_message(:notice, :signed_in) if is_flashing_format?
17
17
  sign_in(resource_name, resource)
18
18
  respond_with resource, :location => after_sign_in_path_for(resource)
19
19
  end
@@ -22,7 +22,7 @@ class Devise::SessionsController < DeviseController
22
22
  def destroy
23
23
  redirect_path = after_sign_out_path_for(resource_name)
24
24
  signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
25
- set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
25
+ set_flash_message :notice, :signed_out if signed_out && is_flashing_format?
26
26
 
27
27
  # We actually need to hardcode this as Rails default responder doesn't
28
28
  # support returning empty response on GET request
@@ -22,7 +22,7 @@ class Devise::UnlocksController < DeviseController
22
22
  self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
23
23
 
24
24
  if resource.errors.empty?
25
- set_flash_message :notice, :unlocked if is_navigational_format?
25
+ set_flash_message :notice, :unlocked if is_flashing_format?
26
26
  respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
27
27
  else
28
28
  respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
@@ -123,7 +123,7 @@ MESSAGE
123
123
  end
124
124
 
125
125
  if notice
126
- set_flash_message :notice, notice if is_navigational_format?
126
+ set_flash_message :notice, notice if is_flashing_format?
127
127
  true
128
128
  end
129
129
  end
@@ -147,12 +147,16 @@ MESSAGE
147
147
  flash[key] = message if message.present?
148
148
  end
149
149
 
150
+ def devise_i18n_options(options)
151
+ options
152
+ end
153
+
150
154
  # Get message for given
151
155
  def find_message(kind, options = {})
152
156
  options[:scope] = "devise.#{controller_name}"
153
157
  options[:default] = Array(options[:default]).unshift(kind.to_sym)
154
158
  options[:resource_name] = resource_name
155
- options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
159
+ options = devise_i18n_options(options)
156
160
  I18n.t("#{options[:resource_name]}.#{kind}", options)
157
161
  end
158
162
 
@@ -1,18 +1,20 @@
1
- class Devise::Mailer < Devise.parent_mailer.constantize
2
- include Devise::Mailers::Helpers
1
+ if defined?(ActionMailer)
2
+ class Devise::Mailer < Devise.parent_mailer.constantize
3
+ include Devise::Mailers::Helpers
3
4
 
4
- def confirmation_instructions(record, token, opts={})
5
- @token = token
6
- devise_mail(record, :confirmation_instructions, opts)
7
- end
5
+ def confirmation_instructions(record, token, opts={})
6
+ @token = token
7
+ devise_mail(record, :confirmation_instructions, opts)
8
+ end
8
9
 
9
- def reset_password_instructions(record, token, opts={})
10
- @token = token
11
- devise_mail(record, :reset_password_instructions, opts)
12
- end
10
+ def reset_password_instructions(record, token, opts={})
11
+ @token = token
12
+ devise_mail(record, :reset_password_instructions, opts)
13
+ end
13
14
 
14
- def unlock_instructions(record, token, opts={})
15
- @token = token
16
- devise_mail(record, :unlock_instructions, opts)
15
+ def unlock_instructions(record, token, opts={})
16
+ @token = token
17
+ devise_mail(record, :unlock_instructions, opts)
18
+ end
17
19
  end
18
20
  end
@@ -4,15 +4,14 @@ en:
4
4
  devise:
5
5
  confirmations:
6
6
  confirmed: "Your account was successfully confirmed."
7
- confirmed_and_signed_in: "Your account was successfully confirmed. You are now signed in."
8
7
  send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
9
8
  send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
10
9
  failure:
11
10
  already_authenticated: "You are already signed in."
12
11
  inactive: "Your account is not activated yet."
13
12
  invalid: "Invalid email or password."
14
- invalid_token: "Invalid authentication token."
15
13
  locked: "Your account is locked."
14
+ last_attempt: "You have one more attempt before your account will be locked."
16
15
  not_found_in_database: "Invalid email or password."
17
16
  timeout: "Your session expired. Please sign in again to continue."
18
17
  unauthenticated: "You need to sign in or sign up before continuing."
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- devise (3.1.2)
4
+ devise (3.2.0)
5
5
  bcrypt-ruby (~> 3.0)
6
6
  orm_adapter (~> 0.1)
7
7
  railties (>= 3.2.6, < 5)
@@ -20,9 +20,14 @@ module Devise
20
20
  autoload :Helpers, 'devise/controllers/helpers'
21
21
  autoload :Rememberable, 'devise/controllers/rememberable'
22
22
  autoload :ScopedViews, 'devise/controllers/scoped_views'
23
+ autoload :SignInOut, 'devise/controllers/sign_in_out'
23
24
  autoload :UrlHelpers, 'devise/controllers/url_helpers'
24
25
  end
25
26
 
27
+ module Hooks
28
+ autoload :Proxy, 'devise/hooks/proxy'
29
+ end
30
+
26
31
  module Mailers
27
32
  autoload :Helpers, 'devise/mailers/helpers'
28
33
  end
@@ -50,15 +55,21 @@ module Devise
50
55
  mattr_accessor :secret_key
51
56
  @@secret_key = nil
52
57
 
53
- # Allow insecure token lookup. Must be used
54
- # temporarily just for migration.
55
- mattr_accessor :allow_insecure_token_lookup
56
- @@allow_insecure_tokens_lookup = false
58
+ [ :allow_insecure_token_lookup,
59
+ :allow_insecure_sign_in_after_confirmation,
60
+ :token_authentication_key ].each do |method|
61
+ class_eval <<-RUBY
62
+ def self.#{method}
63
+ ActiveSupport::Deprecation.warn "Devise.#{method} is deprecated " \
64
+ "and has no effect"
65
+ end
57
66
 
58
- # Allow insecure sign in after confirmation. Must be used
59
- # temporarily just for migration.
60
- mattr_accessor :allow_insecure_sign_in_after_confirmation
61
- @@allow_insecure_sign_in_after_confirmation = false
67
+ def self.#{method}=(val)
68
+ ActiveSupport::Deprecation.warn "Devise.#{method}= is deprecated " \
69
+ "and has no effect"
70
+ end
71
+ RUBY
72
+ end
62
73
 
63
74
  # Custom domain or key for cookies. Not set by default
64
75
  mattr_accessor :rememberable_options
@@ -195,10 +206,6 @@ module Devise
195
206
  mattr_accessor :mailer_sender
196
207
  @@mailer_sender = nil
197
208
 
198
- # Authentication token params key name of choice. E.g. /users/sign_in?some_key=...
199
- mattr_accessor :token_authentication_key
200
- @@token_authentication_key = :auth_token
201
-
202
209
  # Skip session storage for the following strategies
203
210
  mattr_accessor :skip_session_storage
204
211
  @@skip_session_storage = []
@@ -266,6 +273,10 @@ module Devise
266
273
  mattr_accessor :paranoid
267
274
  @@paranoid = false
268
275
 
276
+ # When true, warn user if he just used next-to-last attempt of authentication
277
+ mattr_accessor :last_attempt_warning
278
+ @@last_attempt_warning = false
279
+
269
280
  # Stores the token generator
270
281
  mattr_accessor :token_generator
271
282
  @@token_generator = nil
@@ -3,6 +3,7 @@ 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
6
7
 
7
8
  included do
8
9
  helper_method :warden, :signed_in?, :devise_controller?
@@ -96,84 +97,6 @@ module Devise
96
97
  request.env["devise.allow_params_authentication"] = true
97
98
  end
98
99
 
99
- # Return true if the given scope is signed in session. If no scope given, return
100
- # true if any scope is signed in. Does not run authentication hooks.
101
- def signed_in?(scope=nil)
102
- [ scope || Devise.mappings.keys ].flatten.any? do |_scope|
103
- warden.authenticate?(:scope => _scope)
104
- end
105
- end
106
-
107
- # Sign in a user that already was authenticated. This helper is useful for logging
108
- # users in after sign up.
109
- #
110
- # All options given to sign_in is passed forward to the set_user method in warden.
111
- # The only exception is the :bypass option, which bypass warden callbacks and stores
112
- # the user straight in session. This option is useful in cases the user is already
113
- # signed in, but we want to refresh the credentials in session.
114
- #
115
- # Examples:
116
- #
117
- # sign_in :user, @user # sign_in(scope, resource)
118
- # sign_in @user # sign_in(resource)
119
- # sign_in @user, :event => :authentication # sign_in(resource, options)
120
- # sign_in @user, :store => false # sign_in(resource, options)
121
- # sign_in @user, :bypass => true # sign_in(resource, options)
122
- #
123
- def sign_in(resource_or_scope, *args)
124
- options = args.extract_options!
125
- scope = Devise::Mapping.find_scope!(resource_or_scope)
126
- resource = args.last || resource_or_scope
127
-
128
- expire_session_data_after_sign_in!
129
-
130
- if options[:bypass]
131
- warden.session_serializer.store(resource, scope)
132
- elsif warden.user(scope) == resource && !options.delete(:force)
133
- # Do nothing. User already signed in and we are not forcing it.
134
- true
135
- else
136
- warden.set_user(resource, options.merge!(:scope => scope))
137
- end
138
- end
139
-
140
- # Sign out a given user or scope. This helper is useful for signing out a user
141
- # after deleting accounts. Returns true if there was a logout and false if there
142
- # is no user logged in on the referred scope
143
- #
144
- # Examples:
145
- #
146
- # sign_out :user # sign_out(scope)
147
- # sign_out @user # sign_out(resource)
148
- #
149
- def sign_out(resource_or_scope=nil)
150
- return sign_out_all_scopes unless resource_or_scope
151
- scope = Devise::Mapping.find_scope!(resource_or_scope)
152
- user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
153
-
154
- warden.raw_session.inspect # Without this inspect here. The session does not clear.
155
- warden.logout(scope)
156
- warden.clear_strategies_cache!(:scope => scope)
157
- instance_variable_set(:"@current_#{scope}", nil)
158
-
159
- !!user
160
- end
161
-
162
- # Sign out all active users or scopes. This helper is useful for signing out all roles
163
- # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
164
- # and false if there was no user logged in on all scopes.
165
- def sign_out_all_scopes(lock=true)
166
- users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
167
-
168
- warden.raw_session.inspect
169
- warden.logout
170
- expire_devise_cached_variables!
171
- warden.clear_strategies_cache!
172
- warden.lock! if lock
173
-
174
- users.any?
175
- end
176
-
177
100
  # Returns and delete (if it's navigational format) the url stored in the session for
178
101
  # the given scope. Useful for giving redirect backs after sign up:
179
102
  #
@@ -257,10 +180,6 @@ module Devise
257
180
  redirect_to after_sign_in_path_for(resource)
258
181
  end
259
182
 
260
- def expire_session_data_after_sign_in!
261
- session.keys.grep(/^devise\./).each { |k| session.delete(k) }
262
- end
263
-
264
183
  # Sign out a user and tries to redirect to the url specified by
265
184
  # after_sign_out_path_for.
266
185
  def sign_out_and_redirect(resource_or_scope)
@@ -275,7 +194,7 @@ module Devise
275
194
  def handle_unverified_request
276
195
  sign_out_all_scopes(false)
277
196
  request.env["devise.skip_storage"] = true
278
- expire_devise_cached_variables!
197
+ expire_data_after_sign_out!
279
198
  super # call the default behaviour which resets the session
280
199
  end
281
200
 
@@ -287,10 +206,23 @@ module Devise
287
206
  Devise.navigational_formats.include?(request_format)
288
207
  end
289
208
 
209
+ # Check if flash messages should be emitted. Default is to do it on
210
+ # navigational formats
211
+ def is_flashing_format?
212
+ is_navigational_format?
213
+ end
214
+
290
215
  private
291
216
 
292
- def expire_devise_cached_variables!
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
+ def expire_data_after_sign_out!
293
224
  Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
225
+ super
294
226
  end
295
227
  end
296
228
  end
@@ -1,24 +1,14 @@
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
20
- end
21
-
22
12
  # Remembers the given resource by setting up a cookie
23
13
  def remember_me(resource)
24
14
  return if env["devise.skip_storage"]