devise 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (68) hide show
  1. data/{CHANGELOG.rdoc → CHANGELOG.md} +67 -25
  2. data/Gemfile.lock +13 -12
  3. data/README.md +19 -17
  4. data/app/controllers/devise/confirmations_controller.rb +11 -3
  5. data/app/controllers/devise/registrations_controller.rb +9 -3
  6. data/app/controllers/devise/sessions_controller.rb +1 -1
  7. data/app/mailers/devise/mailer.rb +6 -3
  8. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  9. data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
  10. data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
  11. data/app/views/devise/shared/_links.erb +2 -2
  12. data/config/locales/en.yml +4 -3
  13. data/devise.gemspec +1 -0
  14. data/gemfiles/Gemfile.rails-3.2.x.lock +47 -44
  15. data/lib/devise/controllers/helpers.rb +1 -0
  16. data/lib/devise/controllers/rememberable.rb +1 -0
  17. data/lib/devise/hooks/csrf_cleaner.rb +5 -0
  18. data/lib/devise/hooks/lockable.rb +1 -1
  19. data/lib/devise/hooks/rememberable.rb +2 -1
  20. data/lib/devise/mailers/helpers.rb +0 -6
  21. data/lib/devise/models/authenticatable.rb +9 -16
  22. data/lib/devise/models/confirmable.rb +34 -43
  23. data/lib/devise/models/lockable.rb +15 -17
  24. data/lib/devise/models/recoverable.rb +21 -27
  25. data/lib/devise/models/rememberable.rb +6 -2
  26. data/lib/devise/models/timeoutable.rb +1 -1
  27. data/lib/devise/models/token_authenticatable.rb +4 -1
  28. data/lib/devise/models.rb +8 -12
  29. data/lib/devise/parameter_sanitizer.rb +49 -19
  30. data/lib/devise/rails/routes.rb +12 -9
  31. data/lib/devise/rails/warden_compat.rb +10 -2
  32. data/lib/devise/rails.rb +7 -11
  33. data/lib/devise/strategies/authenticatable.rb +0 -12
  34. data/lib/devise/token_generator.rb +70 -0
  35. data/lib/devise/version.rb +1 -1
  36. data/lib/devise.rb +23 -12
  37. data/lib/generators/active_record/devise_generator.rb +2 -5
  38. data/lib/generators/active_record/templates/migration.rb +0 -1
  39. data/lib/generators/active_record/templates/migration_existing.rb +0 -1
  40. data/lib/generators/devise/orm_helpers.rb +25 -6
  41. data/lib/generators/mongoid/devise_generator.rb +2 -2
  42. data/lib/generators/templates/devise.rb +21 -9
  43. data/test/controllers/helpers_test.rb +1 -1
  44. data/test/controllers/passwords_controller_test.rb +4 -5
  45. data/test/failure_app_test.rb +1 -1
  46. data/test/generators/active_record_generator_test.rb +31 -1
  47. data/test/integration/authenticatable_test.rb +15 -1
  48. data/test/integration/confirmable_test.rb +29 -42
  49. data/test/integration/http_authenticatable_test.rb +1 -1
  50. data/test/integration/lockable_test.rb +11 -14
  51. data/test/integration/recoverable_test.rb +23 -24
  52. data/test/integration/rememberable_test.rb +15 -13
  53. data/test/mailers/confirmation_instructions_test.rb +6 -2
  54. data/test/mailers/reset_password_instructions_test.rb +6 -2
  55. data/test/mailers/unlock_instructions_test.rb +6 -2
  56. data/test/models/confirmable_test.rb +38 -27
  57. data/test/models/lockable_test.rb +15 -5
  58. data/test/models/recoverable_test.rb +20 -48
  59. data/test/models/rememberable_test.rb +8 -0
  60. data/test/models/timeoutable_test.rb +5 -0
  61. data/test/models_test.rb +0 -19
  62. data/test/parameter_sanitizer_test.rb +23 -9
  63. data/test/rails_app/config/initializers/devise.rb +3 -0
  64. data/test/rails_app/lib/shared_admin.rb +3 -0
  65. data/test/rails_app/lib/shared_user.rb +4 -0
  66. data/test/support/helpers.rb +0 -21
  67. metadata +42 -26
  68. data/app/views/devise/_links.erb +0 -3
data/lib/devise/models.rb CHANGED
@@ -56,14 +56,8 @@ module Devise
56
56
  klass.devise_modules.each do |mod|
57
57
  constant = const_get(mod.to_s.classify)
58
58
 
59
- if constant.respond_to?(:required_fields)
60
- constant.required_fields(klass).each do |field|
61
- failed_attributes << field unless instance.respond_to?(field)
62
- end
63
- else
64
- ActiveSupport::Deprecation.warn "The module #{mod} doesn't implement self.required_fields(klass). " \
65
- "Devise uses required_fields to warn developers of any missing fields in their models. " \
66
- "Please implement #{mod}.required_fields(klass) that returns an array of symbols with the required fields."
59
+ constant.required_fields(klass).each do |field|
60
+ failed_attributes << field unless instance.respond_to?(field)
67
61
  end
68
62
  end
69
63
 
@@ -89,11 +83,13 @@ module Devise
89
83
 
90
84
  devise_modules_hook! do
91
85
  include Devise::Models::Authenticatable
92
- selected_modules.each do |m|
93
- if m == :encryptable && !(defined?(Devise::Models::Encryptable))
94
- warn "[DEVISE] You're trying to include :encryptable in your model but it is not bundled with the Devise gem anymore. Please add `devise-encryptable` to your Gemfile to proceed.\n"
95
- end
96
86
 
87
+ if selected_modules.include?(:token_authenticatable)
88
+ ActiveSupport::Deprecation.warn "devise :token_authenticatable is deprecated. " \
89
+ "Please check Devise 3.1 release notes for more information on how to upgrade."
90
+ end
91
+
92
+ selected_modules.each do |m|
97
93
  mod = Devise::Models.const_get(m.to_s.classify)
98
94
 
99
95
  if mod.const_defined?("ClassMethods")
@@ -13,14 +13,25 @@ module Devise
13
13
  if block_given?
14
14
  @blocks[kind] = block
15
15
  else
16
- block = @blocks[kind]
17
- block ? block.call(default_params) : fallback_for(kind)
16
+ default_for(kind)
17
+ end
18
+ end
19
+
20
+ def sanitize(kind)
21
+ if block = @blocks[kind]
22
+ block.call(default_params)
23
+ else
24
+ default_sanitize(kind)
18
25
  end
19
26
  end
20
27
 
21
28
  private
22
29
 
23
- def fallback_for(kind)
30
+ def default_for(kind)
31
+ raise ArgumentError, "a block is expected in Devise base sanitizer"
32
+ end
33
+
34
+ def default_sanitize(kind)
24
35
  default_params
25
36
  end
26
37
 
@@ -30,34 +41,53 @@ module Devise
30
41
  end
31
42
 
32
43
  class ParameterSanitizer < BaseSanitizer
33
- private
34
-
35
- def fallback_for(kind)
36
- if respond_to?(kind, true)
37
- send(kind)
38
- else
39
- raise NotImplementedError, "Devise Parameter Sanitizer doesn't know how to sanitize parameters for #{kind}"
40
- end
44
+ def initialize(*)
45
+ super
46
+ @permitted = Hash.new { |h,k| h[k] = attributes_for(k) }
41
47
  end
42
48
 
43
- # These are the params used to sign in a user so we don't need to
44
- # mass-assign the password param in order to authenticate. Excluding it
45
- # here allows us to construct a new user without sensitive information if
46
- # authentication fails.
47
49
  def sign_in
48
- default_params.permit(*auth_keys + [:password, :remember_me])
50
+ default_params.permit self.for(:sign_in)
49
51
  end
50
52
 
51
53
  def sign_up
52
- default_params.permit(*(auth_keys + [:password, :password_confirmation]))
54
+ default_params.permit self.for(:sign_up)
53
55
  end
54
56
 
55
57
  def account_update
56
- default_params.permit(*(auth_keys + [:password, :password_confirmation, :current_password]))
58
+ default_params.permit self.for(:account_update)
59
+ end
60
+
61
+ private
62
+
63
+ # Change for(kind) to return the values in the @permitted
64
+ # hash, allowing the developer to customize at runtime.
65
+ def default_for(kind)
66
+ @permitted[kind] || raise("No sanitizer provided for #{kind}")
67
+ end
68
+
69
+ def default_sanitize(kind)
70
+ if respond_to?(kind, true)
71
+ send(kind)
72
+ else
73
+ raise NotImplementedError, "Devise doesn't know how to sanitize parameters for #{kind}"
74
+ end
75
+ end
76
+
77
+ def attributes_for(kind)
78
+ case kind
79
+ when :sign_in
80
+ auth_keys + [:password, :remember_me]
81
+ when :sign_up
82
+ auth_keys + [:password, :password_confirmation]
83
+ when :account_update
84
+ auth_keys + [:password, :password_confirmation, :current_password]
85
+ end
57
86
  end
58
87
 
59
88
  def auth_keys
60
- resource_class.authentication_keys.respond_to?(:keys) ? resource_class.authentication_keys.keys : resource_class.authentication_keys
89
+ @auth_keys ||= @resource_class.authentication_keys.respond_to?(:keys) ?
90
+ @resource_class.authentication_keys.keys : @resource_class.authentication_keys
61
91
  end
62
92
  end
63
93
  end
@@ -80,7 +80,8 @@ module ActionDispatch::Routing
80
80
  # * :path_names => configure different path names to overwrite defaults :sign_in, :sign_out, :sign_up,
81
81
  # :password, :confirmation, :unlock.
82
82
  #
83
- # devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
83
+ # devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout',
84
+ # :password => 'secret', :confirmation => 'verification', registration: 'register }
84
85
  #
85
86
  # * :controllers => the controller which should be used. All routes by default points to Devise controllers.
86
87
  # However, if you want them to point to custom controller, you should do:
@@ -191,6 +192,7 @@ module ActionDispatch::Routing
191
192
  #
192
193
  def devise_for(*resources)
193
194
  @devise_finalized = false
195
+ raise_no_secret_key unless Devise.secret_key
194
196
  options = resources.extract_options!
195
197
 
196
198
  options[:as] ||= @scope[:as] if @scope[:as].present?
@@ -222,14 +224,6 @@ module ActionDispatch::Routing
222
224
  routes = mapping.used_routes
223
225
 
224
226
  devise_scope mapping.name do
225
- if block_given?
226
- ActiveSupport::Deprecation.warn "Passing a block to devise_for is deprecated. " \
227
- "Please remove the block from devise_for (only the block, the call to " \
228
- "devise_for must still exist) and call devise_scope :#{mapping.name} do ... end " \
229
- "with the block instead", caller
230
- yield
231
- end
232
-
233
227
  with_devise_exclusive_scope mapping.fullpath, mapping.name, options do
234
228
  routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
235
229
  end
@@ -442,6 +436,15 @@ module ActionDispatch::Routing
442
436
  end
443
437
  end
444
438
 
439
+ def raise_no_secret_key #:nodoc:
440
+ raise <<-ERROR
441
+ Devise.secret_key was not set. Please add the following to your Devise initializer:
442
+
443
+ config.secret_key = '#{SecureRandom.hex(64)}'
444
+
445
+ ERROR
446
+ end
447
+
445
448
  def raise_no_devise_method_error!(klass) #:nodoc:
446
449
  raise "#{klass} does not respond to 'devise' method. This usually means you haven't " \
447
450
  "loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " \
@@ -3,9 +3,17 @@ module Warden::Mixins::Common
3
3
  @request ||= ActionDispatch::Request.new(env)
4
4
  end
5
5
 
6
- # This is called internally by Warden on logout
6
+ # Deprecate: Remove this check once we move to Rails 4 only.
7
+ NULL_STORE =
8
+ defined?(ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash) ?
9
+ ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash : nil
10
+
7
11
  def reset_session!
8
- request.reset_session
12
+ # Calling reset_session on NULL_STORE causes it fail.
13
+ # This is a bug that needs to be fixed in Rails.
14
+ unless NULL_STORE && request.session.is_a?(NULL_STORE)
15
+ request.reset_session
16
+ end
9
17
  end
10
18
 
11
19
  def cookies
data/lib/devise/rails.rb CHANGED
@@ -29,21 +29,17 @@ module Devise
29
29
  end
30
30
  end
31
31
 
32
- initializer "devise.mongoid_version_warning" do
33
- if defined?(Mongoid)
34
- require 'mongoid/version'
35
- if Mongoid::VERSION.to_f < 2.1
36
- puts "\n[DEVISE] Please note that Mongoid versions prior to 2.1 handle dirty model " \
37
- "object attributes in such a way that the Devise `validatable` module will not apply " \
38
- "its usual uniqueness and format validations for the email field. It is recommended " \
39
- "that you upgrade to Mongoid 2.1+ for this and other fixes, but if for some reason you " \
40
- "are unable to do so, you should add these validations manually.\n"
32
+ initializer "devise.secret_key" do
33
+ Devise.token_generator ||=
34
+ if secret_key = Devise.secret_key
35
+ Devise::TokenGenerator.new(
36
+ Devise::CachingKeyGenerator.new(Devise::KeyGenerator.new(secret_key))
37
+ )
41
38
  end
42
- end
43
39
  end
44
40
 
45
41
  initializer "devise.fix_routes_proxy_missing_respond_to_bug" do
46
- # We can get rid of this once we support only Rails > 3.2
42
+ # Deprecate: Remove once we move to Rails 4 only.
47
43
  ActionDispatch::Routing::RoutesProxy.class_eval do
48
44
  def respond_to?(method, include_private = false)
49
45
  super || routes.url_helpers.respond_to?(method)
@@ -26,20 +26,8 @@ module Devise
26
26
  # In case the resource can't be validated, it will fail with the given
27
27
  # unauthenticated_message.
28
28
  def validate(resource, &block)
29
- unless resource
30
- ActiveSupport::Deprecation.warn "an empty resource was given to #{self.class.name}#validate. " \
31
- "Please ensure the resource is not nil", caller
32
- end
33
-
34
29
  result = resource && resource.valid_for_authentication?(&block)
35
30
 
36
- case result
37
- when Symbol, String
38
- ActiveSupport::Deprecation.warn "valid_for_authentication? should return a boolean value"
39
- fail!(result)
40
- return false
41
- end
42
-
43
31
  if result
44
32
  decorate(resource)
45
33
  true
@@ -0,0 +1,70 @@
1
+ # Deprecate: Copied verbatim from Rails source, remove once we move to Rails 4 only.
2
+ require 'thread_safe'
3
+ require 'openssl'
4
+ require 'securerandom'
5
+
6
+ module Devise
7
+ class TokenGenerator
8
+ def initialize(key_generator, digest="SHA256")
9
+ @key_generator = key_generator
10
+ @digest = digest
11
+ end
12
+
13
+ def digest(klass, column, value)
14
+ value.present? && OpenSSL::HMAC.hexdigest(@digest, key_for(column), value.to_s)
15
+ end
16
+
17
+ def generate(klass, column)
18
+ key = key_for(column)
19
+
20
+ loop do
21
+ raw = Devise.friendly_token
22
+ enc = OpenSSL::HMAC.hexdigest(@digest, key, raw)
23
+ break [raw, enc] unless klass.to_adapter.find_first({ column => enc })
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def key_for(column)
30
+ @key_generator.generate_key("Devise #{column}")
31
+ end
32
+ end
33
+
34
+ # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
35
+ # It can be used to derive a number of keys for various purposes from a given secret.
36
+ # This lets Rails applications have a single secure secret, but avoid reusing that
37
+ # key in multiple incompatible contexts.
38
+ class KeyGenerator
39
+ def initialize(secret, options = {})
40
+ @secret = secret
41
+ # The default iterations are higher than required for our key derivation uses
42
+ # on the off chance someone uses this for password storage
43
+ @iterations = options[:iterations] || 2**16
44
+ end
45
+
46
+ # Returns a derived key suitable for use. The default key_size is chosen
47
+ # to be compatible with the default settings of ActiveSupport::MessageVerifier.
48
+ # i.e. OpenSSL::Digest::SHA1#block_length
49
+ def generate_key(salt, key_size=64)
50
+ OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
51
+ end
52
+ end
53
+
54
+ # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
55
+ # re-executing the key generation process when it's called using the same salt and
56
+ # key_size
57
+ class CachingKeyGenerator
58
+ def initialize(key_generator)
59
+ @key_generator = key_generator
60
+ @cache_keys = ThreadSafe::Cache.new
61
+ end
62
+
63
+ # Returns a derived key suitable for use. The default key_size is chosen
64
+ # to be compatible with the default settings of ActiveSupport::MessageVerifier.
65
+ # i.e. OpenSSL::Digest::SHA1#block_length
66
+ def generate_key(salt, key_size=64)
67
+ @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "3.0.0".freeze
2
+ VERSION = "3.1.0".freeze
3
3
  end
data/lib/devise.rb CHANGED
@@ -14,6 +14,7 @@ module Devise
14
14
  autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
15
15
  autoload :TestHelpers, 'devise/test_helpers'
16
16
  autoload :TimeInflector, 'devise/time_inflector'
17
+ autoload :TokenGenerator, 'devise/token_generator'
17
18
 
18
19
  module Controllers
19
20
  autoload :Helpers, 'devise/controllers/helpers'
@@ -45,6 +46,20 @@ module Devise
45
46
  # True values used to check params
46
47
  TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
47
48
 
49
+ # Secret key used by the key generator
50
+ mattr_accessor :secret_key
51
+ @@secret_key = nil
52
+
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
57
+
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
62
+
48
63
  # Custom domain or key for cookies. Not set by default
49
64
  mattr_accessor :rememberable_options
50
65
  @@rememberable_options = {}
@@ -223,17 +238,9 @@ module Devise
223
238
  mattr_accessor :omniauth_path_prefix
224
239
  @@omniauth_path_prefix = nil
225
240
 
226
- def self.encryptor=(value)
227
- warn "\n[DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem.\n"
228
- end
229
-
230
- def self.use_salt_as_remember_token=(value)
231
- warn "\n[DEVISE] Devise.use_salt_as_remember_token is deprecated and has no effect. Please remove it.\n"
232
- end
233
-
234
- def self.apply_schema=(value)
235
- warn "\n[DEVISE] Devise.apply_schema is deprecated and has no effect. Please remove it.\n"
236
- end
241
+ # Set if we should clean up the CSRF Token on authentication
242
+ mattr_accessor :clean_up_csrf_token_on_authentication
243
+ @@clean_up_csrf_token_on_authentication = true
237
244
 
238
245
  # PRIVATE CONFIGURATION
239
246
 
@@ -259,6 +266,10 @@ module Devise
259
266
  mattr_accessor :paranoid
260
267
  @@paranoid = false
261
268
 
269
+ # Stores the token generator
270
+ mattr_accessor :token_generator
271
+ @@token_generator = nil
272
+
262
273
  # Default way to setup Devise. Run rails generate devise_install to create
263
274
  # a fresh initializer with all configuration values.
264
275
  def self.setup
@@ -447,7 +458,7 @@ module Devise
447
458
 
448
459
  # Generate a friendly string randomly to be used as token.
449
460
  def self.friendly_token
450
- SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
461
+ SecureRandom.urlsafe_base64(15).tr('lIO0', 'sxyz')
451
462
  end
452
463
 
453
464
  # constant-time comparison algorithm to prevent timing attacks
@@ -50,7 +50,7 @@ module ActiveRecord
50
50
  t.datetime :remember_created_at
51
51
 
52
52
  ## Trackable
53
- t.integer :sign_in_count, :default => 0
53
+ t.integer :sign_in_count, :default => 0, :null => false
54
54
  t.datetime :current_sign_in_at
55
55
  t.datetime :last_sign_in_at
56
56
  t.string :current_sign_in_ip
@@ -63,12 +63,9 @@ module ActiveRecord
63
63
  # t.string :unconfirmed_email # Only if using reconfirmable
64
64
 
65
65
  ## Lockable
66
- # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
66
+ # t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
67
67
  # t.string :unlock_token # Only if unlock strategy is :email or :both
68
68
  # t.datetime :locked_at
69
-
70
- ## Token authenticatable
71
- # t.string :authentication_token
72
69
  RUBY
73
70
  end
74
71
  end
@@ -14,6 +14,5 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
14
14
  add_index :<%= table_name %>, :reset_password_token, :unique => true
15
15
  # add_index :<%= table_name %>, :confirmation_token, :unique => true
16
16
  # add_index :<%= table_name %>, :unlock_token, :unique => true
17
- # add_index :<%= table_name %>, :authentication_token, :unique => true
18
17
  end
19
18
  end
@@ -15,7 +15,6 @@ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
15
15
  add_index :<%= table_name %>, :reset_password_token, :unique => true
16
16
  # add_index :<%= table_name %>, :confirmation_token, :unique => true
17
17
  # add_index :<%= table_name %>, :unlock_token, :unique => true
18
- # add_index :<%= table_name %>, :authentication_token, :unique => true
19
18
  end
20
19
 
21
20
  def self.down
@@ -2,24 +2,43 @@ module Devise
2
2
  module Generators
3
3
  module OrmHelpers
4
4
  def model_contents
5
- <<-CONTENT
5
+ buffer = <<-CONTENT
6
6
  # Include default devise modules. Others available are:
7
- # :token_authenticatable, :confirmable,
8
- # :lockable, :timeoutable and :omniauthable
7
+ # :confirmable, :lockable, :timeoutable and :omniauthable
9
8
  devise :database_authenticatable, :registerable,
10
9
  :recoverable, :rememberable, :trackable, :validatable
11
10
 
12
11
  CONTENT
12
+ buffer += <<-CONTENT if needs_attr_accessible?
13
+ # Setup accessible (or protected) attributes for your model
14
+ attr_accessible :email, :password, :password_confirmation, :remember_me
15
+
16
+ CONTENT
17
+ buffer
18
+ end
19
+
20
+ def needs_attr_accessible?
21
+ rails_3? && !strong_parameters_enabled?
22
+ end
23
+
24
+ def rails_3?
25
+ Rails::VERSION::MAJOR == 3
13
26
  end
14
27
 
28
+ def strong_parameters_enabled?
29
+ defined?(ActionController::StrongParameters)
30
+ end
31
+
32
+ private
33
+
15
34
  def model_exists?
16
35
  File.exists?(File.join(destination_root, model_path))
17
36
  end
18
-
37
+
19
38
  def migration_exists?(table_name)
20
39
  Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_devise_to_#{table_name}.rb$/).first
21
40
  end
22
-
41
+
23
42
  def migration_path
24
43
  @migration_path ||= File.join("db", "migrate")
25
44
  end
@@ -29,4 +48,4 @@ CONTENT
29
48
  end
30
49
  end
31
50
  end
32
- end
51
+ end
@@ -22,7 +22,7 @@ module Mongoid
22
22
  ## Database authenticatable
23
23
  field :email, :type => String, :default => ""
24
24
  field :encrypted_password, :type => String, :default => ""
25
-
25
+
26
26
  ## Recoverable
27
27
  field :reset_password_token, :type => String
28
28
  field :reset_password_sent_at, :type => Time
@@ -54,4 +54,4 @@ RUBY
54
54
  end
55
55
  end
56
56
  end
57
- end
57
+ end
@@ -1,13 +1,19 @@
1
1
  # Use this hook to configure devise mailer, warden hooks and so forth.
2
2
  # Many of these configuration options can be set straight in your model.
3
3
  Devise.setup do |config|
4
+ # The secret key used by Devise. Devise uses this key to generate
5
+ # random tokens. Changing this key will render invalid all existing
6
+ # confirmation, reset password and unlock tokens in the database.
7
+ config.secret_key = '<%= SecureRandom.hex(64) %>'
8
+
4
9
  # ==> Mailer Configuration
5
10
  # Configure the e-mail address which will be shown in Devise::Mailer,
6
- # note that it will be overwritten if you use your own mailer class with default "from" parameter.
7
- config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
11
+ # note that it will be overwritten if you use your own mailer class
12
+ # with default "from" parameter.
13
+ config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
8
14
 
9
15
  # Configure the class responsible to send e-mails.
10
- # config.mailer = "Devise::Mailer"
16
+ # config.mailer = 'Devise::Mailer'
11
17
 
12
18
  # ==> ORM configuration
13
19
  # Load and configure the ORM. Supports :active_record (default) and
@@ -61,8 +67,8 @@ Devise.setup do |config|
61
67
  # If http headers should be returned for AJAX requests. True by default.
62
68
  # config.http_authenticatable_on_xhr = true
63
69
 
64
- # The realm used in Http Basic Authentication. "Application" by default.
65
- # config.http_authentication_realm = "Application"
70
+ # The realm used in Http Basic Authentication. 'Application' by default.
71
+ # config.http_authentication_realm = 'Application'
66
72
 
67
73
  # It will change confirmation, password recovery and other workflows
68
74
  # to behave the same regardless if the e-mail provided was right or wrong.
@@ -76,6 +82,12 @@ Devise.setup do |config|
76
82
  # passing :skip => :sessions to `devise_for` in your config/routes.rb
77
83
  config.skip_session_storage = [:http_auth]
78
84
 
85
+ # By default, Devise cleans up the CSRF token on authentication to
86
+ # avoid CSRF token fixation attacks. This means that, when using AJAX
87
+ # requests for sign in and sign up, you need to get a new CSRF token
88
+ # from the server. You can disable this option at your own risk.
89
+ # config.clean_up_csrf_token_on_authentication = true
90
+
79
91
  # ==> Configuration for :database_authenticatable
80
92
  # For bcrypt, this is the cost for hashing the password and defaults to 10. If
81
93
  # using other encryptors, it sets how many times you want the password re-encrypted.
@@ -86,7 +98,7 @@ Devise.setup do |config|
86
98
  config.stretches = Rails.env.test? ? 1 : 10
87
99
 
88
100
  # Setup a pepper to generate the encrypted password.
89
- # config.pepper = <%= SecureRandom.hex(64).inspect %>
101
+ # config.pepper = '<%= SecureRandom.hex(64) %>'
90
102
 
91
103
  # ==> Configuration for :confirmable
92
104
  # A period that the user is allowed to access the website even without
@@ -211,7 +223,7 @@ Devise.setup do |config|
211
223
  # should add them to the navigational formats lists.
212
224
  #
213
225
  # The "*/*" below is required to match Internet Explorer requests.
214
- # config.navigational_formats = ["*/*", :html]
226
+ # config.navigational_formats = ['*/*', :html]
215
227
 
216
228
  # The default HTTP method used to sign out a resource. Default is :delete.
217
229
  config.sign_out_via = :delete
@@ -235,12 +247,12 @@ Devise.setup do |config|
235
247
  # is mountable, there are some extra configurations to be taken into account.
236
248
  # The following options are available, assuming the engine is mounted as:
237
249
  #
238
- # mount MyEngine, at: "/my_engine"
250
+ # mount MyEngine, at: '/my_engine'
239
251
  #
240
252
  # The router that invoked `devise_for`, in the example above, would be:
241
253
  # config.router_name = :my_engine
242
254
  #
243
255
  # When using omniauth, Devise cannot automatically set Omniauth path,
244
256
  # so you need to do it manually. For the users scope, it would be:
245
- # config.omniauth_path_prefix = "/my_engine/users/auth"
257
+ # config.omniauth_path_prefix = '/my_engine/users/auth'
246
258
  end
@@ -202,7 +202,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase
202
202
 
203
203
  test 'sign in and redirect uses the stored location' do
204
204
  user = User.new
205
- @controller.session[:"user_return_to"] = "/foo.bar"
205
+ @controller.session[:user_return_to] = "/foo.bar"
206
206
  @mock_warden.expects(:user).with(:user).returns(nil)
207
207
  @mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
208
208
  @controller.expects(:redirect_to).with("/foo.bar")
@@ -4,16 +4,15 @@ class PasswordsControllerTest < ActionController::TestCase
4
4
  tests Devise::PasswordsController
5
5
  include Devise::TestHelpers
6
6
 
7
- def setup
7
+ setup do
8
8
  request.env["devise.mapping"] = Devise.mappings[:user]
9
-
10
- @user = create_user
11
- @user.send_reset_password_instructions
9
+ @user = create_user.tap(&:confirm!)
10
+ @raw = @user.send_reset_password_instructions
12
11
  end
13
12
 
14
13
  def put_update_with_params
15
14
  put :update, "user" => {
16
- "reset_password_token" => @user.reset_password_token, "password" => "123456", "password_confirmation" => "123456"
15
+ "reset_password_token" => @raw, "password" => "123456", "password_confirmation" => "123456"
17
16
  }
18
17
  end
19
18
 
@@ -215,7 +215,7 @@ class FailureTest < ActiveSupport::TestCase
215
215
  }
216
216
  call_failure(env)
217
217
  assert @response.third.body.include?('<h2>Sign in</h2>')
218
- assert @response.third.body.include?('Your account was not activated yet.')
218
+ assert @response.third.body.include?('Your account is not activated yet.')
219
219
  end
220
220
  end
221
221
  end