devise 1.2.1 → 1.3.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.
- data/.travis.yml +7 -1
- data/CHANGELOG.rdoc +21 -1
- data/Gemfile.lock +1 -1
- data/README.rdoc +4 -5
- data/app/controllers/devise/confirmations_controller.rb +14 -6
- data/app/controllers/devise/passwords_controller.rb +7 -6
- data/app/controllers/devise/registrations_controller.rb +12 -10
- data/app/controllers/devise/sessions_controller.rb +23 -1
- data/app/controllers/devise/unlocks_controller.rb +7 -6
- data/config/locales/en.yml +1 -0
- data/lib/devise.rb +7 -8
- data/lib/devise/controllers/helpers.rb +0 -6
- data/lib/devise/controllers/internal_helpers.rb +38 -2
- data/lib/devise/failure_app.rb +4 -10
- data/lib/devise/models.rb +27 -4
- data/lib/devise/models/authenticatable.rb +1 -13
- data/lib/devise/models/confirmable.rb +1 -1
- data/lib/devise/models/database_authenticatable.rb +2 -1
- data/lib/devise/models/recoverable.rb +41 -5
- data/lib/devise/models/validatable.rb +2 -3
- data/lib/devise/omniauth.rb +3 -3
- data/lib/devise/rails.rb +8 -25
- data/lib/devise/rails/routes.rb +8 -0
- data/lib/devise/rails/warden_compat.rb +2 -2
- data/lib/devise/schema.rb +8 -3
- data/lib/devise/strategies/authenticatable.rb +2 -1
- data/lib/devise/version.rb +1 -1
- data/lib/generators/devise/views_generator.rb +3 -9
- data/lib/generators/templates/devise.rb +11 -2
- data/test/controllers/internal_helpers_test.rb +15 -0
- data/test/controllers/sessions_controller_test.rb +17 -0
- data/test/devise_test.rb +0 -3
- data/test/integration/authenticatable_test.rb +27 -7
- data/test/integration/confirmable_test.rb +28 -0
- data/test/integration/lockable_test.rb +35 -1
- data/test/integration/recoverable_test.rb +37 -0
- data/test/integration/registerable_test.rb +45 -0
- data/test/models/database_authenticatable_test.rb +20 -2
- data/test/models/recoverable_test.rb +44 -9
- data/test/models/validatable_test.rb +3 -3
- data/test/models_test.rb +23 -0
- data/test/rails_app/config/initializers/devise.rb +7 -2
- data/test/rails_app/config/routes.rb +2 -0
- data/test/routes_test.rb +7 -0
- metadata +7 -5
data/.travis.yml
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,7 +1,27 @@
|
|
1
|
+
== 1.3.0
|
2
|
+
|
3
|
+
* enhancements
|
4
|
+
* All controllers can now handle different mime types than html using Responders (by github.com/sikachu)
|
5
|
+
* Added reset_password_within as configuration option to send the token for recovery (by github.com/jdguyot)
|
6
|
+
* Bump password length to 128 characters (by github.com/k33l0r)
|
7
|
+
* Add :only as option to devise_for (by github.com/timoschilling)
|
8
|
+
* Allow to override path after sending password instructions (by github.com/irohiroki)
|
9
|
+
* require_no_authentication has its own flash message (by github.com/jackdempsey)
|
10
|
+
|
11
|
+
* bug fix
|
12
|
+
* Fix a bug where configuration options were being included too late
|
13
|
+
* Ensure Devise::TestHelpers can be used to tests Devise internal controllers (by github.com/jwilger)
|
14
|
+
* valid_password? should not choke on empty passwords (by github.com/mikel)
|
15
|
+
* Calling devise more than once does not include previously added modules anymore
|
16
|
+
* downcase_keys before validation
|
17
|
+
|
18
|
+
* backward incompatible changes
|
19
|
+
* authentication_keys are no longer considered when creating the e-mail validations, the previous behavior was buggy. You must double check if you were relying on such behavior.
|
20
|
+
|
1
21
|
== 1.2.1
|
2
22
|
|
3
23
|
* enhancements
|
4
|
-
*
|
24
|
+
* Improve update path messages
|
5
25
|
|
6
26
|
== 1.2.0
|
7
27
|
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -152,7 +152,7 @@ You can access the session for this scope:
|
|
152
152
|
|
153
153
|
After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect. Example: For a :user resource, it will use user_root_path if it exists, otherwise default root_path will be used. This means that you need to set the root inside your routes:
|
154
154
|
|
155
|
-
root :to => "home"
|
155
|
+
root :to => "home#index"
|
156
156
|
|
157
157
|
You can also overwrite after_sign_in_path_for and after_sign_out_path_for to customize your redirect hooks.
|
158
158
|
|
@@ -315,12 +315,11 @@ If you're using RSpec and want the helpers automatically included within all +de
|
|
315
315
|
|
316
316
|
Do not use such helpers for integration tests such as Cucumber or Webrat. Instead, fill in the form or explicitly set the user in session. For more tips, check the wiki (http://wiki.github.com/plataformatec/devise).
|
317
317
|
|
318
|
-
===
|
318
|
+
=== Omniauth
|
319
319
|
|
320
|
-
Devise comes with
|
320
|
+
Devise comes with Omniauth support out of the box to authenticate from other providers. You can read more about Omniauth support in the wiki:
|
321
321
|
|
322
|
-
*
|
323
|
-
* http://github.com/plataformatec/devise/wiki/OAuth2:-Testing
|
322
|
+
* https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
|
324
323
|
|
325
324
|
=== Other ORMs
|
326
325
|
|
@@ -12,10 +12,10 @@ class Devise::ConfirmationsController < ApplicationController
|
|
12
12
|
self.resource = resource_class.send_confirmation_instructions(params[resource_name])
|
13
13
|
|
14
14
|
if resource.errors.empty?
|
15
|
-
set_flash_message
|
16
|
-
|
15
|
+
set_flash_message(:notice, :send_instructions) if is_navigational_format?
|
16
|
+
respond_with resource, :location => after_resending_confirmation_instructions_path_for(resource_name)
|
17
17
|
else
|
18
|
-
render_with_scope :new
|
18
|
+
respond_with_navigational(resource){ render_with_scope :new }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -24,10 +24,18 @@ class Devise::ConfirmationsController < ApplicationController
|
|
24
24
|
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
25
25
|
|
26
26
|
if resource.errors.empty?
|
27
|
-
set_flash_message
|
28
|
-
|
27
|
+
set_flash_message(:notice, :confirmed) if is_navigational_format?
|
28
|
+
sign_in(resource_name, resource)
|
29
|
+
respond_with_navigational(resource){ redirect_to redirect_location(resource_name, resource) }
|
29
30
|
else
|
30
|
-
render_with_scope :new
|
31
|
+
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
|
31
32
|
end
|
32
33
|
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
# The path used after resending confirmation instructions.
|
38
|
+
def after_resending_confirmation_instructions_path_for(resource_name)
|
39
|
+
new_session_path(resource_name)
|
40
|
+
end
|
33
41
|
end
|
@@ -13,10 +13,10 @@ class Devise::PasswordsController < ApplicationController
|
|
13
13
|
self.resource = resource_class.send_reset_password_instructions(params[resource_name])
|
14
14
|
|
15
15
|
if resource.errors.empty?
|
16
|
-
set_flash_message
|
17
|
-
|
16
|
+
set_flash_message(:notice, :send_instructions) if is_navigational_format?
|
17
|
+
respond_with resource, :location => new_session_path(resource_name)
|
18
18
|
else
|
19
|
-
render_with_scope :new
|
19
|
+
respond_with_navigational(resource){ render_with_scope :new }
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -32,10 +32,11 @@ class Devise::PasswordsController < ApplicationController
|
|
32
32
|
self.resource = resource_class.reset_password_by_token(params[resource_name])
|
33
33
|
|
34
34
|
if resource.errors.empty?
|
35
|
-
set_flash_message
|
36
|
-
|
35
|
+
set_flash_message(:notice, :updated) if is_navigational_format?
|
36
|
+
sign_in(resource_name, resource)
|
37
|
+
respond_with resource, :location => redirect_location(resource_name, resource)
|
37
38
|
else
|
38
|
-
render_with_scope :edit
|
39
|
+
respond_with_navigational(resource){ render_with_scope :edit }
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
@@ -15,16 +15,17 @@ class Devise::RegistrationsController < ApplicationController
|
|
15
15
|
|
16
16
|
if resource.save
|
17
17
|
if resource.active_for_authentication?
|
18
|
-
set_flash_message :notice, :signed_up
|
19
|
-
|
18
|
+
set_flash_message :notice, :signed_up if is_navigational_format?
|
19
|
+
sign_in(resource_name, resource)
|
20
|
+
respond_with resource, :location => redirect_location(resource_name, resource)
|
20
21
|
else
|
21
|
-
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s
|
22
|
+
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
|
22
23
|
expire_session_data_after_sign_in!
|
23
|
-
|
24
|
+
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
|
24
25
|
end
|
25
26
|
else
|
26
27
|
clean_up_passwords(resource)
|
27
|
-
render_with_scope :new
|
28
|
+
respond_with_navigational(resource) { render_with_scope :new }
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -36,20 +37,21 @@ class Devise::RegistrationsController < ApplicationController
|
|
36
37
|
# PUT /resource
|
37
38
|
def update
|
38
39
|
if resource.update_with_password(params[resource_name])
|
39
|
-
set_flash_message :notice, :updated
|
40
|
+
set_flash_message :notice, :updated if is_navigational_format?
|
40
41
|
sign_in resource_name, resource, :bypass => true
|
41
|
-
|
42
|
+
respond_with resource, :location => after_update_path_for(resource)
|
42
43
|
else
|
43
44
|
clean_up_passwords(resource)
|
44
|
-
render_with_scope :edit
|
45
|
+
respond_with_navigational(resource){ render_with_scope :edit }
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
48
49
|
# DELETE /resource
|
49
50
|
def destroy
|
50
51
|
resource.destroy
|
51
|
-
|
52
|
-
set_flash_message :notice, :destroyed
|
52
|
+
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
53
|
+
set_flash_message :notice, :destroyed if is_navigational_format?
|
54
|
+
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
|
53
55
|
end
|
54
56
|
|
55
57
|
# GET /resource/cancel
|
@@ -11,6 +11,17 @@ class Devise::SessionsController < ApplicationController
|
|
11
11
|
# POST /resource/sign_in
|
12
12
|
def create
|
13
13
|
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
|
14
|
+
|
15
|
+
# In the running app, the previous line would actually cause this method to
|
16
|
+
# exit by throwing `:warden` if the authentication failed. Unfortunately,
|
17
|
+
# this doesn't happen in the Rails test environment if you have included the
|
18
|
+
# Devise::TestHelpers (see `Devise::TestHelpers::TestWarden#authenticate!`),
|
19
|
+
# which makes it difficult to unit test extensions to this controller. Since
|
20
|
+
# the resource is nil if authentication fails, just short-circuit the method
|
21
|
+
# in that case. This should not affect the running app.
|
22
|
+
|
23
|
+
return if resource.nil?
|
24
|
+
|
14
25
|
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
15
26
|
sign_in(resource_name, resource)
|
16
27
|
respond_with resource, :location => redirect_location(resource_name, resource)
|
@@ -19,7 +30,18 @@ class Devise::SessionsController < ApplicationController
|
|
19
30
|
# GET /resource/sign_out
|
20
31
|
def destroy
|
21
32
|
signed_in = signed_in?(resource_name)
|
22
|
-
|
33
|
+
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
23
34
|
set_flash_message :notice, :signed_out if signed_in
|
35
|
+
|
36
|
+
# We actually need to hardcode this, as Rails default responder doesn't
|
37
|
+
# support returning empty response on GET request
|
38
|
+
respond_to do |format|
|
39
|
+
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
|
40
|
+
format.all do
|
41
|
+
method = "to_#{request_format}"
|
42
|
+
text = {}.respond_to?(method) ? {}.send(method) : ""
|
43
|
+
render :text => text, :status => :ok
|
44
|
+
end
|
45
|
+
end
|
24
46
|
end
|
25
47
|
end
|
@@ -13,10 +13,10 @@ class Devise::UnlocksController < ApplicationController
|
|
13
13
|
self.resource = resource_class.send_unlock_instructions(params[resource_name])
|
14
14
|
|
15
15
|
if resource.errors.empty?
|
16
|
-
set_flash_message :notice, :send_instructions
|
17
|
-
|
16
|
+
set_flash_message :notice, :send_instructions if is_navigational_format?
|
17
|
+
respond_with resource, :location => new_session_path(resource_name)
|
18
18
|
else
|
19
|
-
render_with_scope :new
|
19
|
+
respond_with_navigational(resource){ render_with_scope :new }
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -25,10 +25,11 @@ class Devise::UnlocksController < ApplicationController
|
|
25
25
|
self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
|
26
26
|
|
27
27
|
if resource.errors.empty?
|
28
|
-
set_flash_message :notice, :unlocked
|
29
|
-
|
28
|
+
set_flash_message :notice, :unlocked if is_navigational_format?
|
29
|
+
sign_in(resource_name, resource)
|
30
|
+
respond_with_navigational(resource){ redirect_to redirect_location(resource_name, resource) }
|
30
31
|
else
|
31
|
-
render_with_scope :new
|
32
|
+
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
data/config/locales/en.yml
CHANGED
@@ -12,6 +12,7 @@ en:
|
|
12
12
|
|
13
13
|
devise:
|
14
14
|
failure:
|
15
|
+
already_authenticated: 'You are already signed in.'
|
15
16
|
unauthenticated: 'You need to sign in or sign up before continuing.'
|
16
17
|
unconfirmed: 'You have to confirm your account before continuing.'
|
17
18
|
locked: 'Your account is locked.'
|
data/lib/devise.rb
CHANGED
@@ -96,7 +96,7 @@ module Devise
|
|
96
96
|
|
97
97
|
# Range validation for password length
|
98
98
|
mattr_accessor :password_length
|
99
|
-
@@password_length = 6..
|
99
|
+
@@password_length = 6..128
|
100
100
|
|
101
101
|
# The time the user will be remembered without asking for credentials again.
|
102
102
|
mattr_accessor :remember_for
|
@@ -171,6 +171,10 @@ module Devise
|
|
171
171
|
mattr_accessor :reset_password_keys
|
172
172
|
@@reset_password_keys = [ :email ]
|
173
173
|
|
174
|
+
# Time interval you can reset your password with a reset password key
|
175
|
+
mattr_accessor :reset_password_within
|
176
|
+
@@reset_password_within = nil
|
177
|
+
|
174
178
|
# The default scope which is used by warden.
|
175
179
|
mattr_accessor :default_scope
|
176
180
|
@@default_scope = nil
|
@@ -238,12 +242,6 @@ module Devise
|
|
238
242
|
omniauth_configs.keys
|
239
243
|
end
|
240
244
|
|
241
|
-
def self.cookie_domain=(value)
|
242
|
-
ActiveSupport::Deprecation.warn "Devise.cookie_domain=(value) is deprecated. "
|
243
|
-
"Please use Devise.cookie_options = { :domain => value } instead."
|
244
|
-
self.cookie_options[:domain] = value
|
245
|
-
end
|
246
|
-
|
247
245
|
# Get the mailer class from the mailer reference object.
|
248
246
|
def self.mailer
|
249
247
|
if defined?(ActiveSupport::Dependencies::ClassCache)
|
@@ -319,7 +317,8 @@ module Devise
|
|
319
317
|
|
320
318
|
if options[:model]
|
321
319
|
path = (options[:model] == true ? "devise/models/#{module_name}" : options[:model])
|
322
|
-
|
320
|
+
camelized = ActiveSupport::Inflector.camelize(module_name.to_s)
|
321
|
+
Devise::Models.send(:autoload, camelized.to_sym, path)
|
323
322
|
end
|
324
323
|
|
325
324
|
Devise::Mapping.add_module module_name
|
@@ -80,12 +80,6 @@ module Devise
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
def anybody_signed_in?
|
84
|
-
ActiveSupport::Deprecation.warn "Devise#anybody_signed_in? is deprecated. "
|
85
|
-
"Please use Devise#signed_in?(nil) instead."
|
86
|
-
signed_in?
|
87
|
-
end
|
88
|
-
|
89
83
|
# Sign in a user that already was authenticated. This helper is useful for logging
|
90
84
|
# users in after sign up.
|
91
85
|
#
|
@@ -7,6 +7,19 @@ module Devise
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
include Devise::Controllers::ScopedViews
|
9
9
|
|
10
|
+
MIME_REFERENCES = Mime::HTML.respond_to?(:ref)
|
11
|
+
|
12
|
+
# Helper used by FailureApp and Devise controllers to retrieve proper formats.
|
13
|
+
def self.request_format(request)
|
14
|
+
if request.format.respond_to?(:ref)
|
15
|
+
request.format.ref
|
16
|
+
elsif MIME_REFERENCES
|
17
|
+
request.format
|
18
|
+
elsif request.format # Rails < 3.0.4
|
19
|
+
request.format.to_sym
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
10
23
|
included do
|
11
24
|
helper DeviseHelper
|
12
25
|
|
@@ -52,14 +65,30 @@ module Devise
|
|
52
65
|
|
53
66
|
protected
|
54
67
|
|
68
|
+
def request_format
|
69
|
+
@request_format ||= Devise::Controllers::InternalHelpers.request_format(request)
|
70
|
+
end
|
71
|
+
|
55
72
|
# Checks whether it's a devise mapped resource or not.
|
56
73
|
def is_devise_resource? #:nodoc:
|
57
|
-
unknown_action!
|
74
|
+
unknown_action! <<-MESSAGE unless devise_mapping
|
75
|
+
Could not find devise mapping for path #{request.fullpath.inspect}.
|
76
|
+
Maybe you forgot to wrap your route inside the scope block? For example:
|
77
|
+
|
78
|
+
devise_scope :user do
|
79
|
+
match "/some/route" => "some_devise_controller"
|
80
|
+
end
|
81
|
+
MESSAGE
|
58
82
|
end
|
59
83
|
|
60
84
|
# Check whether it's navigational format, such as :html or :iphone, or not.
|
61
85
|
def is_navigational_format?
|
62
|
-
Devise.navigational_formats.include?(
|
86
|
+
Devise.navigational_formats.include?(request_format)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns real navigational formats which are supported by Rails
|
90
|
+
def navigational_formats
|
91
|
+
@navigational_formats ||= Devise.navigational_formats.select{ |format| Mime::EXTENSION_LOOKUP[format.to_s] }
|
63
92
|
end
|
64
93
|
|
65
94
|
def unknown_action!(msg)
|
@@ -85,6 +114,7 @@ module Devise
|
|
85
114
|
def require_no_authentication
|
86
115
|
if warden.authenticated?(resource_name)
|
87
116
|
resource = warden.user(resource_name)
|
117
|
+
flash[:alert] = I18n.t("devise.failure.already_authenticated")
|
88
118
|
redirect_to after_sign_in_path_for(resource)
|
89
119
|
end
|
90
120
|
end
|
@@ -114,6 +144,12 @@ module Devise
|
|
114
144
|
def clean_up_passwords(object) #:nodoc:
|
115
145
|
object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
|
116
146
|
end
|
147
|
+
|
148
|
+
def respond_with_navigational(*args, &block)
|
149
|
+
respond_with(*args) do |format|
|
150
|
+
format.any(*navigational_formats, &block)
|
151
|
+
end
|
152
|
+
end
|
117
153
|
end
|
118
154
|
end
|
119
155
|
end
|
data/lib/devise/failure_app.rb
CHANGED
@@ -101,7 +101,9 @@ module Devise
|
|
101
101
|
|
102
102
|
def recall_app(app)
|
103
103
|
controller, action = app.split("#")
|
104
|
-
|
104
|
+
controller_name = ActiveSupport::Inflector.camelize(controller)
|
105
|
+
controller_klass = ActiveSupport::Inflector.constantize("#{controller_name}Controller")
|
106
|
+
controller_klass.action(action)
|
105
107
|
end
|
106
108
|
|
107
109
|
def warden
|
@@ -128,16 +130,8 @@ module Devise
|
|
128
130
|
session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
|
129
131
|
end
|
130
132
|
|
131
|
-
MIME_REFERENCES = Mime::HTML.respond_to?(:ref)
|
132
|
-
|
133
133
|
def request_format
|
134
|
-
@request_format ||=
|
135
|
-
request.format.ref
|
136
|
-
elsif MIME_REFERENCES
|
137
|
-
request.format
|
138
|
-
else # Rails < 3.0.4
|
139
|
-
request.format.to_sym
|
140
|
-
end
|
134
|
+
@request_format ||= Devise::Controllers::InternalHelpers.request_format(request)
|
141
135
|
end
|
142
136
|
end
|
143
137
|
end
|
data/lib/devise/models.rb
CHANGED
@@ -17,6 +17,9 @@ module Devise
|
|
17
17
|
# inside the given class.
|
18
18
|
#
|
19
19
|
def self.config(mod, *accessors) #:nodoc:
|
20
|
+
(class << mod; self; end).send :attr_accessor, :available_configs
|
21
|
+
mod.available_configs = accessors
|
22
|
+
|
20
23
|
accessors.each do |accessor|
|
21
24
|
mod.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
22
25
|
def #{accessor}
|
@@ -46,13 +49,33 @@ module Devise
|
|
46
49
|
#
|
47
50
|
def devise(*modules)
|
48
51
|
include Devise::Models::Authenticatable
|
49
|
-
options = modules.extract_options
|
50
|
-
|
52
|
+
options = modules.extract_options!.dup
|
53
|
+
|
54
|
+
selected_modules = modules.map(&:to_sym).uniq.sort_by do |s|
|
51
55
|
Devise::ALL.index(s) || -1 # follow Devise::ALL order
|
52
|
-
|
56
|
+
end
|
53
57
|
|
54
58
|
devise_modules_hook! do
|
55
|
-
|
59
|
+
selected_modules.each do |m|
|
60
|
+
mod = Devise::Models.const_get(m.to_s.classify)
|
61
|
+
|
62
|
+
if mod.const_defined?("ClassMethods")
|
63
|
+
class_mod = mod.const_get("ClassMethods")
|
64
|
+
extend class_mod
|
65
|
+
|
66
|
+
if class_mod.respond_to?(:available_configs)
|
67
|
+
available_configs = class_mod.available_configs
|
68
|
+
available_configs.each do |config|
|
69
|
+
next unless options.key?(config)
|
70
|
+
send(:"#{config}=", options.delete(config))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
include mod
|
76
|
+
end
|
77
|
+
|
78
|
+
self.devise_modules |= selected_modules
|
56
79
|
options.each { |key, value| send(:"#{key}=", value) }
|
57
80
|
end
|
58
81
|
end
|