devise 3.3.0 → 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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +29 -20
  3. data/CHANGELOG.md +219 -102
  4. data/CODE_OF_CONDUCT.md +22 -0
  5. data/CONTRIBUTING.md +2 -0
  6. data/Gemfile +3 -2
  7. data/Gemfile.lock +101 -80
  8. data/MIT-LICENSE +1 -1
  9. data/README.md +87 -43
  10. data/Rakefile +2 -1
  11. data/app/controllers/devise/confirmations_controller.rb +5 -1
  12. data/app/controllers/devise/omniauth_callbacks_controller.rb +4 -0
  13. data/app/controllers/devise/passwords_controller.rb +14 -4
  14. data/app/controllers/devise/registrations_controller.rb +10 -11
  15. data/app/controllers/devise/sessions_controller.rb +7 -2
  16. data/app/controllers/devise/unlocks_controller.rb +3 -0
  17. data/app/controllers/devise_controller.rb +44 -21
  18. data/app/mailers/devise/mailer.rb +4 -0
  19. data/app/views/devise/confirmations/new.html.erb +7 -3
  20. data/app/views/devise/mailer/password_change.html.erb +3 -0
  21. data/app/views/devise/passwords/edit.html.erb +14 -5
  22. data/app/views/devise/passwords/new.html.erb +7 -3
  23. data/app/views/devise/registrations/edit.html.erb +19 -9
  24. data/app/views/devise/registrations/new.html.erb +18 -7
  25. data/app/views/devise/sessions/new.html.erb +15 -6
  26. data/app/views/devise/shared/{_links.erb → _links.html.erb} +1 -1
  27. data/app/views/devise/unlocks/new.html.erb +7 -3
  28. data/config/locales/en.yml +4 -2
  29. data/devise.gemspec +2 -2
  30. data/gemfiles/Gemfile.rails-3.2-stable.lock +54 -48
  31. data/gemfiles/Gemfile.rails-4.0-stable +1 -0
  32. data/gemfiles/Gemfile.rails-4.0-stable.lock +63 -59
  33. data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.1-stable} +3 -5
  34. data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
  35. data/gemfiles/Gemfile.rails-4.2-stable +30 -0
  36. data/gemfiles/Gemfile.rails-4.2-stable.lock +193 -0
  37. data/lib/devise/controllers/helpers.rb +12 -6
  38. data/lib/devise/controllers/rememberable.rb +9 -2
  39. data/lib/devise/controllers/sign_in_out.rb +2 -8
  40. data/lib/devise/controllers/store_location.rb +3 -1
  41. data/lib/devise/controllers/url_helpers.rb +7 -9
  42. data/lib/devise/encryptor.rb +22 -0
  43. data/lib/devise/failure_app.rb +56 -14
  44. data/lib/devise/hooks/timeoutable.rb +5 -7
  45. data/lib/devise/mapping.rb +2 -1
  46. data/lib/devise/models/authenticatable.rb +28 -28
  47. data/lib/devise/models/confirmable.rb +51 -17
  48. data/lib/devise/models/database_authenticatable.rb +17 -11
  49. data/lib/devise/models/lockable.rb +7 -3
  50. data/lib/devise/models/recoverable.rb +23 -15
  51. data/lib/devise/models/rememberable.rb +56 -22
  52. data/lib/devise/models/timeoutable.rb +0 -6
  53. data/lib/devise/models/trackable.rb +1 -2
  54. data/lib/devise/models/validatable.rb +3 -3
  55. data/lib/devise/models.rb +1 -1
  56. data/lib/devise/rails/routes.rb +33 -27
  57. data/lib/devise/rails.rb +1 -1
  58. data/lib/devise/strategies/authenticatable.rb +8 -6
  59. data/lib/devise/strategies/database_authenticatable.rb +2 -1
  60. data/lib/devise/strategies/rememberable.rb +13 -3
  61. data/lib/devise/test_helpers.rb +2 -2
  62. data/lib/devise/version.rb +1 -1
  63. data/lib/devise.rb +39 -37
  64. data/lib/generators/active_record/devise_generator.rb +2 -1
  65. data/lib/generators/active_record/templates/migration.rb +1 -1
  66. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  67. data/lib/generators/devise/controllers_generator.rb +44 -0
  68. data/lib/generators/devise/views_generator.rb +14 -3
  69. data/lib/generators/templates/controllers/README +14 -0
  70. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  71. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  72. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  73. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  74. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  75. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  76. data/lib/generators/templates/devise.rb +19 -13
  77. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  78. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  79. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  80. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  81. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  82. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  83. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +2 -2
  84. data/test/controllers/custom_registrations_controller_test.rb +6 -1
  85. data/test/controllers/helper_methods_test.rb +21 -0
  86. data/test/controllers/helpers_test.rb +5 -0
  87. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  88. data/test/controllers/internal_helpers_test.rb +10 -4
  89. data/test/controllers/load_hooks_controller_test.rb +19 -0
  90. data/test/controllers/passwords_controller_test.rb +1 -1
  91. data/test/controllers/sessions_controller_test.rb +3 -3
  92. data/test/controllers/url_helpers_test.rb +6 -0
  93. data/test/devise_test.rb +3 -3
  94. data/test/failure_app_test.rb +47 -0
  95. data/test/generators/controllers_generator_test.rb +48 -0
  96. data/test/generators/views_generator_test.rb +8 -1
  97. data/test/helpers/devise_helper_test.rb +9 -12
  98. data/test/integration/authenticatable_test.rb +1 -1
  99. data/test/integration/database_authenticatable_test.rb +11 -0
  100. data/test/integration/http_authenticatable_test.rb +1 -1
  101. data/test/integration/omniauthable_test.rb +12 -10
  102. data/test/integration/recoverable_test.rb +13 -0
  103. data/test/integration/rememberable_test.rb +50 -3
  104. data/test/integration/timeoutable_test.rb +13 -18
  105. data/test/mailers/confirmation_instructions_test.rb +1 -1
  106. data/test/mapping_test.rb +7 -0
  107. data/test/models/authenticatable_test.rb +10 -0
  108. data/test/models/confirmable_test.rb +99 -42
  109. data/test/models/database_authenticatable_test.rb +20 -0
  110. data/test/models/lockable_test.rb +45 -17
  111. data/test/models/recoverable_test.rb +62 -7
  112. data/test/models/rememberable_test.rb +68 -97
  113. data/test/models/validatable_test.rb +5 -5
  114. data/test/models_test.rb +15 -6
  115. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  116. data/test/rails_app/app/controllers/admins_controller.rb +0 -5
  117. data/test/rails_app/app/controllers/custom/registrations_controller.rb +10 -0
  118. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  119. data/test/rails_app/app/mailers/users/mailer.rb +0 -9
  120. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  121. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  122. data/test/rails_app/config/application.rb +1 -1
  123. data/test/rails_app/config/environments/production.rb +6 -2
  124. data/test/rails_app/config/environments/test.rb +7 -2
  125. data/test/rails_app/config/initializers/devise.rb +12 -15
  126. data/test/rails_app/config/routes.rb +6 -3
  127. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -2
  128. data/test/rails_app/lib/shared_user.rb +1 -1
  129. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  130. data/test/rails_test.rb +9 -0
  131. data/test/support/helpers.rb +13 -6
  132. data/test/support/integration.rb +2 -2
  133. data/test/test_helper.rb +5 -0
  134. data/test/test_helpers_test.rb +22 -7
  135. data/test/test_models.rb +2 -2
  136. data/test/time_helpers.rb +137 -0
  137. metadata +58 -8
  138. data/gemfiles/Gemfile.rails-head.lock +0 -190
@@ -27,7 +27,7 @@ module Devise
27
27
 
28
28
  # Receives a resource and check if it is valid by calling valid_for_authentication?
29
29
  # An optional block that will be triggered while validating can be optionally
30
- # given as parameter. Check Devise::Models::Authenticable.valid_for_authentication?
30
+ # given as parameter. Check Devise::Models::Authenticatable.valid_for_authentication?
31
31
  # for more information.
32
32
  #
33
33
  # In case the resource can't be validated, it will fail with the given
@@ -36,7 +36,6 @@ module Devise
36
36
  result = resource && resource.valid_for_authentication?(&block)
37
37
 
38
38
  if result
39
- decorate(resource)
40
39
  true
41
40
  else
42
41
  if resource
@@ -47,7 +46,7 @@ module Devise
47
46
  end
48
47
 
49
48
  # Get values from params and set in the resource.
50
- def decorate(resource)
49
+ def remember_me(resource)
51
50
  resource.remember_me = remember_me? if resource.respond_to?(:remember_me=)
52
51
  end
53
52
 
@@ -58,7 +57,7 @@ module Devise
58
57
 
59
58
  # Check if this is a valid strategy for http authentication by:
60
59
  #
61
- # * Validating if the model allows params authentication;
60
+ # * Validating if the model allows http authentication;
62
61
  # * If any of the authorization headers were sent;
63
62
  # * If all authentication keys are present;
64
63
  #
@@ -109,14 +108,17 @@ module Devise
109
108
  params_auth_hash.is_a?(Hash)
110
109
  end
111
110
 
112
- # Check if password is present.
111
+ # Note: unlike `Model.valid_password?`, this method does not actually
112
+ # ensure that the password in the params matches the password stored in
113
+ # the database. It only checks if the password is *present*. Do not rely
114
+ # on this method for validating that a given password is correct.
113
115
  def valid_password?
114
116
  password.present?
115
117
  end
116
118
 
117
119
  # Helper to decode credentials from HTTP.
118
120
  def decode_credentials
119
- return [] unless request.authorization && request.authorization =~ /^Basic (.*)/m
121
+ return [] unless request.authorization && request.authorization =~ /^Basic (.*)/mi
120
122
  Base64.decode64($1).split(/:/, 2)
121
123
  end
122
124
 
@@ -5,10 +5,11 @@ module Devise
5
5
  # Default strategy for signing in a user, based on their email and password in the database.
6
6
  class DatabaseAuthenticatable < Authenticatable
7
7
  def authenticate!
8
- resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
8
+ resource = password.present? && mapping.to.find_for_database_authentication(authentication_hash)
9
9
  encrypted = false
10
10
 
11
11
  if validate(resource){ encrypted = true; resource.valid_password?(password) }
12
+ remember_me(resource)
12
13
  resource.after_database_authentication
13
14
  success!(resource)
14
15
  end
@@ -25,15 +25,25 @@ module Devise
25
25
  end
26
26
 
27
27
  if validate(resource)
28
+ remember_me(resource) if extend_remember_me?(resource)
29
+ resource.after_remembered
28
30
  success!(resource)
29
31
  end
30
32
  end
31
33
 
34
+ # No need to clean up the CSRF when using rememberable.
35
+ # In fact, cleaning it up here would be a bug because
36
+ # rememberable is triggered on GET requests which means
37
+ # we would render a page on first access with all csrf
38
+ # tokens expired.
39
+ def clean_up_csrf?
40
+ false
41
+ end
42
+
32
43
  private
33
44
 
34
- def decorate(resource)
35
- super
36
- resource.extend_remember_period = mapping.to.extend_remember_period if resource.respond_to?(:extend_remember_period=)
45
+ def extend_remember_me?(resource)
46
+ resource.respond_to?(:extend_remember_period) && resource.extend_remember_period
37
47
  end
38
48
 
39
49
  def remember_me?
@@ -26,11 +26,11 @@ module Devise
26
26
 
27
27
  # Quick access to Warden::Proxy.
28
28
  def warden #:nodoc:
29
- @warden ||= begin
29
+ @request.env['warden'] ||= begin
30
30
  manager = Warden::Manager.new(nil) do |config|
31
31
  config.merge! Devise.warden_config
32
32
  end
33
- @request.env['warden'] = Warden::Proxy.new(@request.env, manager)
33
+ Warden::Proxy.new(@request.env, manager)
34
34
  end
35
35
  end
36
36
 
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "3.3.0".freeze
2
+ VERSION = "3.5.10".freeze
3
3
  end
data/lib/devise.rb CHANGED
@@ -4,9 +4,11 @@ require 'active_support/dependencies'
4
4
  require 'orm_adapter'
5
5
  require 'set'
6
6
  require 'securerandom'
7
+ require 'responders'
7
8
 
8
9
  module Devise
9
10
  autoload :Delegator, 'devise/delegator'
11
+ autoload :Encryptor, 'devise/encryptor'
10
12
  autoload :FailureApp, 'devise/failure_app'
11
13
  autoload :OmniAuth, 'devise/omniauth'
12
14
  autoload :ParameterFilter, 'devise/parameter_filter'
@@ -56,22 +58,6 @@ module Devise
56
58
  mattr_accessor :secret_key
57
59
  @@secret_key = nil
58
60
 
59
- [ :allow_insecure_token_lookup,
60
- :allow_insecure_sign_in_after_confirmation,
61
- :token_authentication_key ].each do |method|
62
- class_eval <<-RUBY
63
- def self.#{method}
64
- ActiveSupport::Deprecation.warn "Devise.#{method} is deprecated " \
65
- "and has no effect"
66
- end
67
-
68
- def self.#{method}=(val)
69
- ActiveSupport::Deprecation.warn "Devise.#{method}= is deprecated " \
70
- "and has no effect"
71
- end
72
- RUBY
73
- end
74
-
75
61
  # Custom domain or key for cookies. Not set by default
76
62
  mattr_accessor :rememberable_options
77
63
  @@rememberable_options = {}
@@ -86,7 +72,7 @@ module Devise
86
72
 
87
73
  # Keys used when authenticating a user.
88
74
  mattr_accessor :authentication_keys
89
- @@authentication_keys = [ :email ]
75
+ @@authentication_keys = [:email]
90
76
 
91
77
  # Request keys used when authenticating a user.
92
78
  mattr_accessor :request_keys
@@ -94,7 +80,7 @@ module Devise
94
80
 
95
81
  # Keys that should be case-insensitive.
96
82
  mattr_accessor :case_insensitive_keys
97
- @@case_insensitive_keys = [ :email ]
83
+ @@case_insensitive_keys = [:email]
98
84
 
99
85
  # Keys that should have whitespace stripped.
100
86
  mattr_accessor :strip_whitespace_keys
@@ -120,7 +106,7 @@ module Devise
120
106
  # an one (and only one) @ exists in the given string. This is mainly
121
107
  # to give user feedback and not to assert the e-mail validity.
122
108
  mattr_accessor :email_regexp
123
- @@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
109
+ @@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/
124
110
 
125
111
  # Range validation for password length
126
112
  mattr_accessor :password_length
@@ -149,7 +135,7 @@ module Devise
149
135
 
150
136
  # Defines which key will be used when confirming an account.
151
137
  mattr_accessor :confirmation_keys
152
- @@confirmation_keys = [ :email ]
138
+ @@confirmation_keys = [:email]
153
139
 
154
140
  # Defines if email should be reconfirmable.
155
141
  # False by default for backwards compatibility.
@@ -160,14 +146,14 @@ module Devise
160
146
  mattr_accessor :timeout_in
161
147
  @@timeout_in = 30.minutes
162
148
 
163
- # Authentication token expiration on timeout
164
- mattr_accessor :expire_auth_token_on_timeout
165
- @@expire_auth_token_on_timeout = false
166
-
167
149
  # Used to encrypt password. Please generate one with rake secret.
168
150
  mattr_accessor :pepper
169
151
  @@pepper = nil
170
152
 
153
+ # Used to enable sending notification to user when their password is changed
154
+ mattr_accessor :send_password_change_notification
155
+ @@send_password_change_notification = false
156
+
171
157
  # Scoped views. Since it relies on fallbacks to render default views, it's
172
158
  # turned off by default.
173
159
  mattr_accessor :scoped_views
@@ -180,7 +166,7 @@ module Devise
180
166
 
181
167
  # Defines which key will be used when locking and unlocking an account
182
168
  mattr_accessor :unlock_keys
183
- @@unlock_keys = [ :email ]
169
+ @@unlock_keys = [:email]
184
170
 
185
171
  # Defines which strategy can be used to unlock an account.
186
172
  # Values: :email, :time, :both
@@ -197,12 +183,16 @@ module Devise
197
183
 
198
184
  # Defines which key will be used when recovering the password for an account
199
185
  mattr_accessor :reset_password_keys
200
- @@reset_password_keys = [ :email ]
186
+ @@reset_password_keys = [:email]
201
187
 
202
188
  # Time interval you can reset your password with a reset password key
203
189
  mattr_accessor :reset_password_within
204
190
  @@reset_password_within = 6.hours
205
191
 
192
+ # When set to false, resetting a password does not automatically sign in a user
193
+ mattr_accessor :sign_in_after_reset_password
194
+ @@sign_in_after_reset_password = true
195
+
206
196
  # The default scope which is used by warden.
207
197
  mattr_accessor :default_scope
208
198
  @@default_scope = nil
@@ -245,7 +235,7 @@ module Devise
245
235
  mattr_accessor :router_name
246
236
  @@router_name = nil
247
237
 
248
- # Set the omniauth path prefix so it can be overridden when
238
+ # Set the OmniAuth path prefix so it can be overridden when
249
239
  # Devise is used in a mountable engine
250
240
  mattr_accessor :omniauth_path_prefix
251
241
  @@omniauth_path_prefix = nil
@@ -260,7 +250,7 @@ module Devise
260
250
  mattr_reader :mappings
261
251
  @@mappings = ActiveSupport::OrderedHash.new
262
252
 
263
- # Omniauth configurations.
253
+ # OmniAuth configurations.
264
254
  mattr_reader :omniauth_configs
265
255
  @@omniauth_configs = ActiveSupport::OrderedHash.new
266
256
 
@@ -280,7 +270,7 @@ module Devise
280
270
 
281
271
  # When true, warn user if they just used next-to-last attempt of authentication
282
272
  mattr_accessor :last_attempt_warning
283
- @@last_attempt_warning = false
273
+ @@last_attempt_warning = true
284
274
 
285
275
  # Stores the token generator
286
276
  mattr_accessor :token_generator
@@ -339,7 +329,12 @@ module Devise
339
329
  mapping
340
330
  end
341
331
 
342
- # Make Devise aware of an 3rd party Devise-module (like invitable). For convenience.
332
+ # Register available devise modules. For the standard modules that Devise provides, this method is
333
+ # called from lib/devise/modules.rb. Third-party modules need to be added explicitly using this method.
334
+ #
335
+ # Note that adding a module using this method does not cause it to be used in the authentication
336
+ # process. That requires that the module be listed in the arguments passed to the 'devise' method
337
+ # in the model class definition.
343
338
  #
344
339
  # == Options:
345
340
  #
@@ -347,6 +342,7 @@ module Devise
347
342
  # +controller+ - Symbol representing the name of an existing or custom *controller* for this module.
348
343
  # +route+ - Symbol representing the named *route* helper for this module.
349
344
  # +strategy+ - Symbol representing if this module got a custom *strategy*.
345
+ # +insert_at+ - Integer representing the order in which this module's model will be included
350
346
  #
351
347
  # All values, except :model, accept also a boolean and will have the same name as the given module
352
348
  # name.
@@ -356,10 +352,12 @@ module Devise
356
352
  # Devise.add_module(:party_module)
357
353
  # Devise.add_module(:party_module, strategy: true, controller: :sessions)
358
354
  # Devise.add_module(:party_module, model: 'party_module/model')
355
+ # Devise.add_module(:party_module, insert_at: 0)
359
356
  #
360
357
  def self.add_module(module_name, options = {})
361
- ALL << module_name
362
- options.assert_valid_keys(:strategy, :model, :controller, :route, :no_input)
358
+ options.assert_valid_keys(:strategy, :model, :controller, :route, :no_input, :insert_at)
359
+
360
+ ALL.insert (options[:insert_at] || -1), module_name
363
361
 
364
362
  if strategy = options[:strategy]
365
363
  strategy = (strategy == true ? module_name : strategy)
@@ -416,7 +414,7 @@ module Devise
416
414
  @@warden_config_blocks << block
417
415
  end
418
416
 
419
- # Specify an omniauth provider.
417
+ # Specify an OmniAuth provider.
420
418
  #
421
419
  # config.omniauth :github, APP_ID, APP_SECRET
422
420
  #
@@ -444,8 +442,8 @@ module Devise
444
442
  Devise::Controllers::UrlHelpers.generate_helpers!
445
443
  end
446
444
 
447
- # A method used internally to setup warden manager from the Rails initialize
448
- # block.
445
+ # A method used internally to complete the setup of warden manager after routes are loaded.
446
+ # See lib/devise/rails/routes.rb - ActionDispatch::Routing::RouteSet#finalize_with_devise!
449
447
  def self.configure_warden! #:nodoc:
450
448
  @@warden_configured ||= begin
451
449
  warden_config.failure_app = Devise::Delegator.new
@@ -473,8 +471,12 @@ module Devise
473
471
  end
474
472
 
475
473
  # Generate a friendly string randomly to be used as token.
476
- def self.friendly_token
477
- SecureRandom.urlsafe_base64(15).tr('lIO0', 'sxyz')
474
+ # By default, length is 20 characters.
475
+ def self.friendly_token(length = 20)
476
+ # To calculate real characters, we must perform this operation.
477
+ # See SecureRandom.urlsafe_base64
478
+ rlength = (length * 3) / 4
479
+ SecureRandom.urlsafe_base64(rlength).tr('lIO0', 'sxyz')
478
480
  end
479
481
 
480
482
  # constant-time comparison algorithm to prevent timing attacks
@@ -83,7 +83,8 @@ RUBY
83
83
  end
84
84
 
85
85
  def postgresql?
86
- ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
86
+ config = ActiveRecord::Base.configurations[Rails.env]
87
+ config && config['adapter'] == 'postgresql'
87
88
  end
88
89
  end
89
90
  end
@@ -7,7 +7,7 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
7
7
  t.<%= attribute.type %> :<%= attribute.name %>
8
8
  <% end -%>
9
9
 
10
- t.timestamps
10
+ t.timestamps null: false
11
11
  end
12
12
 
13
13
  add_index :<%= table_name %>, :email, unique: true
@@ -8,7 +8,7 @@ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
8
8
  <% end -%>
9
9
 
10
10
  # Uncomment below if timestamps were not included in your original model.
11
- # t.timestamps
11
+ # t.timestamps null: false
12
12
  end
13
13
 
14
14
  add_index :<%= table_name %>, :email, unique: true
@@ -0,0 +1,44 @@
1
+ require 'rails/generators/base'
2
+
3
+ module Devise
4
+ module Generators
5
+ class ControllersGenerator < Rails::Generators::Base
6
+ CONTROLLERS = %w(confirmations passwords registrations sessions unlocks omniauth_callbacks).freeze
7
+
8
+ desc <<-DESC.strip_heredoc
9
+ Create inherited Devise controllers in your app/controllers folder.
10
+
11
+ Use -c to specify which controller you want to overwrite.
12
+ If you do no specify a controller, all controllers will be created.
13
+ For example:
14
+
15
+ rails generate devise:controllers users -c=sessions
16
+
17
+ This will create a controller class at app/controllers/users/sessions_controller.rb like this:
18
+
19
+ class Users::ConfirmationsController < Devise::ConfirmationsController
20
+ content...
21
+ end
22
+ DESC
23
+
24
+ source_root File.expand_path("../../templates/controllers", __FILE__)
25
+ argument :scope, required: true,
26
+ desc: "The scope to create controllers in, e.g. users, admins"
27
+ class_option :controllers, aliases: "-c", type: :array,
28
+ desc: "Select specific controllers to generate (#{CONTROLLERS.join(', ')})"
29
+
30
+ def create_controllers
31
+ @scope_prefix = scope.blank? ? '' : (scope.camelize + '::')
32
+ controllers = options[:controllers] || CONTROLLERS
33
+ controllers.each do |name|
34
+ template "#{name}_controller.rb",
35
+ "app/controllers/#{scope}/#{name}_controller.rb"
36
+ end
37
+ end
38
+
39
+ def show_readme
40
+ readme "README" if behavior == :invoke
41
+ end
42
+ end
43
+ end
44
+ end
@@ -47,7 +47,7 @@ module Devise
47
47
  def view_directory(name, _target_path = nil)
48
48
  directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
49
49
  if scope
50
- content.gsub "devise/shared/links", "#{scope}/shared/links"
50
+ content.gsub "devise/shared/links", "#{plural_scope}/shared/links"
51
51
  else
52
52
  content
53
53
  end
@@ -55,7 +55,11 @@ module Devise
55
55
  end
56
56
 
57
57
  def target_path
58
- @target_path ||= "app/views/#{scope || :devise}"
58
+ @target_path ||= "app/views/#{plural_scope || :devise}"
59
+ end
60
+
61
+ def plural_scope
62
+ @plural_scope ||= scope.presence && scope.underscore.pluralize
59
63
  end
60
64
  end
61
65
 
@@ -83,6 +87,13 @@ module Devise
83
87
  source_root File.expand_path("../../templates/simple_form_for", __FILE__)
84
88
  desc "Copies simple form enabled views to your application."
85
89
  hide!
90
+
91
+ def copy_views
92
+ if options[:views]
93
+ options[:views].delete('mailer')
94
+ end
95
+ super
96
+ end
86
97
  end
87
98
 
88
99
  class ErbGenerator < Rails::Generators::Base #:nodoc:
@@ -111,7 +122,7 @@ module Devise
111
122
  end
112
123
 
113
124
  def target_path
114
- "app/views/#{scope || :devise}/mailer"
125
+ "app/views/#{plural_scope || :devise}/mailer"
115
126
  end
116
127
  end
117
128
 
@@ -0,0 +1,14 @@
1
+ ===============================================================================
2
+
3
+ Some setup you must do manually if you haven't yet:
4
+
5
+ Ensure you have overridden routes for generated controllers in your routes.rb.
6
+ For example:
7
+
8
+ Rails.application.routes.draw do
9
+ devise_for :users, controllers: {
10
+ sessions: 'users/sessions'
11
+ }
12
+ end
13
+
14
+ ===============================================================================
@@ -0,0 +1,28 @@
1
+ class <%= @scope_prefix %>ConfirmationsController < Devise::ConfirmationsController
2
+ # GET /resource/confirmation/new
3
+ # def new
4
+ # super
5
+ # end
6
+
7
+ # POST /resource/confirmation
8
+ # def create
9
+ # super
10
+ # end
11
+
12
+ # GET /resource/confirmation?confirmation_token=abcdef
13
+ # def show
14
+ # super
15
+ # end
16
+
17
+ # protected
18
+
19
+ # The path used after resending confirmation instructions.
20
+ # def after_resending_confirmation_instructions_path_for(resource_name)
21
+ # super(resource_name)
22
+ # end
23
+
24
+ # The path used after confirmation.
25
+ # def after_confirmation_path_for(resource_name, resource)
26
+ # super(resource_name, resource)
27
+ # end
28
+ end
@@ -0,0 +1,28 @@
1
+ class <%= @scope_prefix %>OmniauthCallbacksController < Devise::OmniauthCallbacksController
2
+ # You should configure your model like this:
3
+ # devise :omniauthable, omniauth_providers: [:twitter]
4
+
5
+ # You should also create an action method in this controller like this:
6
+ # def twitter
7
+ # end
8
+
9
+ # More info at:
10
+ # https://github.com/plataformatec/devise#omniauth
11
+
12
+ # GET|POST /resource/auth/twitter
13
+ # def passthru
14
+ # super
15
+ # end
16
+
17
+ # GET|POST /users/auth/twitter/callback
18
+ # def failure
19
+ # super
20
+ # end
21
+
22
+ # protected
23
+
24
+ # The path used when OmniAuth fails
25
+ # def after_omniauth_failure_path_for(scope)
26
+ # super(scope)
27
+ # end
28
+ end
@@ -0,0 +1,32 @@
1
+ class <%= @scope_prefix %>PasswordsController < Devise::PasswordsController
2
+ # GET /resource/password/new
3
+ # def new
4
+ # super
5
+ # end
6
+
7
+ # POST /resource/password
8
+ # def create
9
+ # super
10
+ # end
11
+
12
+ # GET /resource/password/edit?reset_password_token=abcdef
13
+ # def edit
14
+ # super
15
+ # end
16
+
17
+ # PUT /resource/password
18
+ # def update
19
+ # super
20
+ # end
21
+
22
+ # protected
23
+
24
+ # def after_resetting_password_path_for(resource)
25
+ # super(resource)
26
+ # end
27
+
28
+ # The path used after sending reset password instructions
29
+ # def after_sending_reset_password_instructions_path_for(resource_name)
30
+ # super(resource_name)
31
+ # end
32
+ end
@@ -0,0 +1,60 @@
1
+ class <%= @scope_prefix %>RegistrationsController < Devise::RegistrationsController
2
+ # before_filter :configure_sign_up_params, only: [:create]
3
+ # before_filter :configure_account_update_params, only: [:update]
4
+
5
+ # GET /resource/sign_up
6
+ # def new
7
+ # super
8
+ # end
9
+
10
+ # POST /resource
11
+ # def create
12
+ # super
13
+ # end
14
+
15
+ # GET /resource/edit
16
+ # def edit
17
+ # super
18
+ # end
19
+
20
+ # PUT /resource
21
+ # def update
22
+ # super
23
+ # end
24
+
25
+ # DELETE /resource
26
+ # def destroy
27
+ # super
28
+ # end
29
+
30
+ # GET /resource/cancel
31
+ # Forces the session data which is usually expired after sign
32
+ # in to be expired now. This is useful if the user wants to
33
+ # cancel oauth signing in/up in the middle of the process,
34
+ # removing all OAuth session data.
35
+ # def cancel
36
+ # super
37
+ # end
38
+
39
+ # protected
40
+
41
+ # If you have extra params to permit, append them to the sanitizer.
42
+ # def configure_sign_up_params
43
+ # devise_parameter_sanitizer.for(:sign_up) << :attribute
44
+ # end
45
+
46
+ # If you have extra params to permit, append them to the sanitizer.
47
+ # def configure_account_update_params
48
+ # devise_parameter_sanitizer.for(:account_update) << :attribute
49
+ # end
50
+
51
+ # The path used after sign up.
52
+ # def after_sign_up_path_for(resource)
53
+ # super(resource)
54
+ # end
55
+
56
+ # The path used after sign up for inactive accounts.
57
+ # def after_inactive_sign_up_path_for(resource)
58
+ # super(resource)
59
+ # end
60
+ end
@@ -0,0 +1,25 @@
1
+ class <%= @scope_prefix %>SessionsController < Devise::SessionsController
2
+ # before_filter :configure_sign_in_params, only: [:create]
3
+
4
+ # GET /resource/sign_in
5
+ # def new
6
+ # super
7
+ # end
8
+
9
+ # POST /resource/sign_in
10
+ # def create
11
+ # super
12
+ # end
13
+
14
+ # DELETE /resource/sign_out
15
+ # def destroy
16
+ # super
17
+ # end
18
+
19
+ # protected
20
+
21
+ # If you have extra params to permit, append them to the sanitizer.
22
+ # def configure_sign_in_params
23
+ # devise_parameter_sanitizer.for(:sign_in) << :attribute
24
+ # end
25
+ end
@@ -0,0 +1,28 @@
1
+ class <%= @scope_prefix %>UnlocksController < Devise::UnlocksController
2
+ # GET /resource/unlock/new
3
+ # def new
4
+ # super
5
+ # end
6
+
7
+ # POST /resource/unlock
8
+ # def create
9
+ # super
10
+ # end
11
+
12
+ # GET /resource/unlock?unlock_token=abcdef
13
+ # def show
14
+ # super
15
+ # end
16
+
17
+ # protected
18
+
19
+ # The path used after sending unlock password instructions
20
+ # def after_sending_unlock_instructions_path_for(resource)
21
+ # super(resource)
22
+ # end
23
+
24
+ # The path used after unlocking the resource
25
+ # def after_unlock_path_for(resource)
26
+ # super(resource)
27
+ # end
28
+ end