devise 2.1.0 → 2.1.2

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 (60) hide show
  1. data/CHANGELOG.rdoc +34 -17
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +45 -45
  4. data/README.md +23 -18
  5. data/Rakefile +1 -1
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +6 -0
  7. data/app/controllers/devise/passwords_controller.rb +9 -0
  8. data/app/controllers/devise/sessions_controller.rb +1 -0
  9. data/app/controllers/devise_controller.rb +16 -5
  10. data/app/views/devise/confirmations/new.html.erb +1 -1
  11. data/app/views/devise/passwords/edit.html.erb +1 -1
  12. data/app/views/devise/passwords/new.html.erb +1 -1
  13. data/app/views/devise/registrations/edit.html.erb +1 -1
  14. data/app/views/devise/registrations/new.html.erb +1 -1
  15. data/app/views/devise/sessions/new.html.erb +1 -1
  16. data/app/views/devise/unlocks/new.html.erb +1 -1
  17. data/config/locales/en.yml +1 -0
  18. data/devise.gemspec +2 -2
  19. data/lib/devise.rb +5 -1
  20. data/lib/devise/controllers/helpers.rb +11 -8
  21. data/lib/devise/hooks/timeoutable.rb +6 -3
  22. data/lib/devise/models.rb +5 -4
  23. data/lib/devise/models/authenticatable.rb +49 -12
  24. data/lib/devise/models/confirmable.rb +2 -2
  25. data/lib/devise/models/database_authenticatable.rb +1 -1
  26. data/lib/devise/models/lockable.rb +8 -4
  27. data/lib/devise/models/recoverable.rb +1 -1
  28. data/lib/devise/omniauth.rb +1 -1
  29. data/lib/devise/omniauth/url_helpers.rb +0 -15
  30. data/lib/devise/rails/routes.rb +59 -25
  31. data/lib/devise/strategies/authenticatable.rb +16 -5
  32. data/lib/devise/strategies/base.rb +5 -0
  33. data/lib/devise/strategies/database_authenticatable.rb +1 -2
  34. data/lib/devise/strategies/rememberable.rb +5 -3
  35. data/lib/devise/strategies/token_authenticatable.rb +1 -2
  36. data/lib/devise/version.rb +1 -1
  37. data/lib/generators/devise/views_generator.rb +6 -0
  38. data/lib/generators/mongoid/devise_generator.rb +5 -2
  39. data/lib/generators/templates/devise.rb +20 -4
  40. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +3 -3
  41. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +3 -3
  42. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +3 -3
  43. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +3 -3
  44. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +3 -3
  45. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +3 -3
  46. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +3 -3
  47. data/test/controllers/helpers_test.rb +6 -7
  48. data/test/controllers/sessions_controller_test.rb +22 -15
  49. data/test/integration/authenticatable_test.rb +109 -63
  50. data/test/integration/recoverable_test.rb +6 -0
  51. data/test/integration/timeoutable_test.rb +28 -2
  52. data/test/models/recoverable_test.rb +3 -3
  53. data/test/models_test.rb +3 -3
  54. data/test/omniauth/url_helpers_test.rb +1 -8
  55. data/test/rails_app/app/controllers/admins_controller.rb +5 -0
  56. data/test/rails_app/config/routes.rb +11 -1
  57. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +3 -0
  58. data/test/support/assertions.rb +6 -8
  59. data/test/support/integration.rb +2 -1
  60. metadata +14 -19
@@ -14,4 +14,4 @@
14
14
  <div><%= f.submit "Sign in" %></div>
15
15
  <% end %>
16
16
 
17
- <%= render :partial => "devise/shared/links" %>
17
+ <%= render "devise/shared/links" %>
@@ -9,4 +9,4 @@
9
9
  <div><%= f.submit "Resend unlock instructions" %></div>
10
10
  <% end %>
11
11
 
12
- <%= render :partial => "devise/shared/links" %>
12
+ <%= render "devise/shared/links" %>
@@ -29,6 +29,7 @@ en:
29
29
  updated: 'Your password was changed successfully. You are now signed in.'
30
30
  updated_not_active: 'Your password was changed successfully.'
31
31
  send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
32
+ no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
32
33
  confirmations:
33
34
  send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
34
35
  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.'
@@ -18,8 +18,8 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- test/*`.split("\n")
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_dependency("warden", "~> 1.1.1")
22
- s.add_dependency("orm_adapter", "~> 0.0.7")
21
+ s.add_dependency("warden", "~> 1.2.1")
22
+ s.add_dependency("orm_adapter", "~> 0.1")
23
23
  s.add_dependency("bcrypt-ruby", "~> 3.0")
24
24
  s.add_dependency("railties", "~> 3.1")
25
25
  end
@@ -10,7 +10,6 @@ module Devise
10
10
  autoload :FailureApp, 'devise/failure_app'
11
11
  autoload :OmniAuth, 'devise/omniauth'
12
12
  autoload :ParamFilter, 'devise/param_filter'
13
- autoload :Schema, 'devise/schema'
14
13
  autoload :TestHelpers, 'devise/test_helpers'
15
14
 
16
15
  module Controllers
@@ -200,6 +199,11 @@ module Devise
200
199
  # to provide custom routes.
201
200
  mattr_accessor :router_name
202
201
  @@router_name = nil
202
+
203
+ # Set the omniauth path prefix so it can be overriden when
204
+ # Devise is used in a mountable engine
205
+ mattr_accessor :omniauth_path_prefix
206
+ @@omniauth_path_prefix = nil
203
207
 
204
208
  def self.encryptor=(value)
205
209
  warn "\n[DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem.\n"
@@ -88,8 +88,8 @@ module Devise
88
88
  # Return true if the given scope is signed in session. If no scope given, return
89
89
  # true if any scope is signed in. Does not run authentication hooks.
90
90
  def signed_in?(scope=nil)
91
- [ scope || Devise.mappings.keys ].flatten.any? do |scope|
92
- warden.authenticate?(:scope => scope)
91
+ [ scope || Devise.mappings.keys ].flatten.any? do |_scope|
92
+ warden.authenticate?(:scope => _scope)
93
93
  end
94
94
  end
95
95
 
@@ -126,8 +126,8 @@ module Devise
126
126
  end
127
127
 
128
128
  # Sign out a given user or scope. This helper is useful for signing out a user
129
- # after deleting accounts. Returns true if there was a logout and false if there is no user logged in
130
- # on the referred scope
129
+ # after deleting accounts. Returns true if there was a logout and false if there
130
+ # is no user logged in on the referred scope
131
131
  #
132
132
  # Examples:
133
133
  #
@@ -141,6 +141,7 @@ module Devise
141
141
 
142
142
  warden.raw_session.inspect # Without this inspect here. The session does not clear.
143
143
  warden.logout(scope)
144
+ warden.clear_strategies_cache!(:scope => scope)
144
145
  instance_variable_set(:"@current_#{scope}", nil)
145
146
 
146
147
  !!user
@@ -149,13 +150,15 @@ module Devise
149
150
  # Sign out all active users or scopes. This helper is useful for signing out all roles
150
151
  # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
151
152
  # and false if there was no user logged in on all scopes.
152
- def sign_out_all_scopes
153
+ def sign_out_all_scopes(lock=true)
153
154
  users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
154
155
 
155
156
  warden.raw_session.inspect
156
157
  warden.logout
157
158
  expire_devise_cached_variables!
158
-
159
+ warden.clear_strategies_cache!
160
+ warden.lock! if lock
161
+
159
162
  users.any?
160
163
  end
161
164
 
@@ -253,8 +256,8 @@ module Devise
253
256
  # Overwrite Rails' handle unverified request to sign out all scopes,
254
257
  # clear run strategies and remove cached variables.
255
258
  def handle_unverified_request
256
- sign_out_all_scopes
257
- warden.clear_strategies_cache!
259
+ sign_out_all_scopes(false)
260
+ request.env["devise.skip_storage"] = true
258
261
  expire_devise_cached_variables!
259
262
  super # call the default behaviour which resets the session
260
263
  end
@@ -5,17 +5,20 @@
5
5
  # verify timeout in the following request.
6
6
  Warden::Manager.after_set_user do |record, warden, options|
7
7
  scope = options[:scope]
8
+ env = warden.request.env
8
9
 
9
10
  if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
10
11
  last_request_at = warden.session(scope)['last_request_at']
11
12
 
12
- if record.timedout?(last_request_at)
13
+ if record.timedout?(last_request_at) && !env['devise.skip_timeout']
13
14
  warden.logout(scope)
14
- record.reset_authentication_token! if record.respond_to?(:reset_authentication_token!) && record.expire_auth_token_on_timeout
15
+ if record.respond_to?(:expire_auth_token_on_timeout) && record.expire_auth_token_on_timeout
16
+ record.reset_authentication_token!
17
+ end
15
18
  throw :warden, :scope => scope, :message => :timeout
16
19
  end
17
20
 
18
- unless warden.request.env['devise.skip_trackable']
21
+ unless env['devise.skip_trackable']
19
22
  warden.session(scope)['last_request_at'] = Time.now.utc
20
23
  end
21
24
  end
@@ -27,7 +27,7 @@ module Devise
27
27
  # inside the given class.
28
28
  #
29
29
  def self.config(mod, *accessors) #:nodoc:
30
- (class << mod; self; end).send :attr_accessor, :available_configs
30
+ class << mod; attr_accessor :available_configs; end
31
31
  mod.available_configs = accessors
32
32
 
33
33
  accessors.each do |accessor|
@@ -51,12 +51,13 @@ module Devise
51
51
 
52
52
  def self.check_fields!(klass)
53
53
  failed_attributes = []
54
+ instance = klass.new
54
55
 
55
56
  klass.devise_modules.each do |mod|
56
- instance = klass.new
57
+ constant = const_get(mod.to_s.classify)
57
58
 
58
- if const_get(mod.to_s.classify).respond_to?(:required_fields)
59
- const_get(mod.to_s.classify).required_fields(klass).each do |field|
59
+ if constant.respond_to?(:required_fields)
60
+ constant.required_fields(klass).each do |field|
60
61
  failed_attributes << field unless instance.respond_to?(field)
61
62
  end
62
63
  else
@@ -93,22 +93,10 @@ module Devise
93
93
  def authenticatable_salt
94
94
  end
95
95
 
96
- def devise_mailer
97
- Devise.mailer
98
- end
99
-
100
96
  def headers_for(name)
101
97
  {}
102
98
  end
103
99
 
104
- def downcase_keys
105
- self.class.case_insensitive_keys.each { |k| self[k].try(:downcase!) }
106
- end
107
-
108
- def strip_whitespace
109
- self.class.strip_whitespace_keys.each { |k| self[k].try(:strip!) }
110
- end
111
-
112
100
  array = %w(serializable_hash)
113
101
  # to_xml does not call serializable_hash on 3.1
114
102
  array << "to_xml" if Rails::VERSION::STRING[0,3] == "3.1"
@@ -134,6 +122,55 @@ module Devise
134
122
  RUBY
135
123
  end
136
124
 
125
+ protected
126
+
127
+ def devise_mailer
128
+ Devise.mailer
129
+ end
130
+
131
+ # This is an internal method called every time Devise needs
132
+ # to send a notification/mail. This can be overriden if you
133
+ # need to customize the e-mail delivery logic. For instance,
134
+ # if you are using a queue to deliver e-mails (delayed job,
135
+ # sidekiq, resque, etc), you must add the delivery to the queue
136
+ # just after the transaction was committed. To achieve this,
137
+ # you can override send_devise_notification to store the
138
+ # deliveries until the after_commit callback is triggered:
139
+ #
140
+ # class User
141
+ # devise :database_authenticatable, :confirmable
142
+ #
143
+ # after_commit :send_pending_notifications
144
+ #
145
+ # protected
146
+ #
147
+ # def send_devise_notification(notification)
148
+ # pending_notifications << notification
149
+ # end
150
+ #
151
+ # def send_pending_notifications
152
+ # pending_notifications.each do |n|
153
+ # devise_mailer.send(n, self).deliver
154
+ # end
155
+ # end
156
+ #
157
+ # def pending_notifications
158
+ # @pending_notifications ||= []
159
+ # end
160
+ # end
161
+ #
162
+ def send_devise_notification(notification)
163
+ devise_mailer.send(notification, self).deliver
164
+ end
165
+
166
+ def downcase_keys
167
+ self.class.case_insensitive_keys.each { |k| self[k].try(:downcase!) }
168
+ end
169
+
170
+ def strip_whitespace
171
+ self.class.strip_whitespace_keys.each { |k| self[k].try(:strip!) }
172
+ end
173
+
137
174
  module ClassMethods
138
175
  Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys,
139
176
  :case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage)
@@ -78,7 +78,7 @@ module Devise
78
78
  @reconfirmation_required = false
79
79
 
80
80
  generate_confirmation_token! if self.confirmation_token.blank?
81
- self.devise_mailer.confirmation_instructions(self).deliver
81
+ send_devise_notification(:confirmation_instructions)
82
82
  end
83
83
 
84
84
  # Resend confirmation token. This method does not need to generate a new token.
@@ -125,7 +125,7 @@ module Devise
125
125
  # instructions on creation. This can be overriden
126
126
  # in models to map to a nice sign up e-mail.
127
127
  def send_on_create_confirmation_instructions
128
- self.devise_mailer.confirmation_instructions(self).deliver
128
+ send_devise_notification(:confirmation_instructions)
129
129
  end
130
130
 
131
131
  # Callback to overwrite if confirmation is required or not.
@@ -64,7 +64,7 @@ module Devise
64
64
  result = if valid_password?(current_password)
65
65
  update_attributes(params, *options)
66
66
  else
67
- self.attributes = params
67
+ self.assign_attributes(params, *options)
68
68
  self.valid?
69
69
  self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
70
70
  false
@@ -38,11 +38,11 @@ module Devise
38
38
  self.locked_at = Time.now.utc
39
39
 
40
40
  if unlock_strategy_enabled?(:email)
41
- generate_unlock_token
41
+ generate_unlock_token!
42
42
  send_unlock_instructions
43
+ else
44
+ save(:validate => false)
43
45
  end
44
-
45
- save(:validate => false)
46
46
  end
47
47
 
48
48
  # Unlock a user by cleaning locked_at and failed_attempts.
@@ -60,7 +60,7 @@ module Devise
60
60
 
61
61
  # Send unlock instructions by email
62
62
  def send_unlock_instructions
63
- self.devise_mailer.unlock_instructions(self).deliver
63
+ send_devise_notification(:unlock_instructions)
64
64
  end
65
65
 
66
66
  # Resend the unlock instructions if the user is locked.
@@ -123,6 +123,10 @@ module Devise
123
123
  self.unlock_token = self.class.unlock_token
124
124
  end
125
125
 
126
+ def generate_unlock_token!
127
+ generate_unlock_token && save(:validate => false)
128
+ end
129
+
126
130
  # Tells if the lock is expired if :time unlock strategy is active
127
131
  def lock_expired?
128
132
  if unlock_strategy_enabled?(:time)
@@ -45,7 +45,7 @@ module Devise
45
45
  # Resets reset password token and send reset password instructions by email
46
46
  def send_reset_password_instructions
47
47
  generate_reset_password_token! if should_generate_reset_token?
48
- self.devise_mailer.reset_password_instructions(self).deliver
48
+ send_devise_notification(:reset_password_instructions)
49
49
  end
50
50
 
51
51
  # Checks if the reset password token sent is within the limit time.
@@ -1,7 +1,7 @@
1
1
  begin
2
2
  require "omniauth"
3
3
  require "omniauth/version"
4
- rescue LoadError => e
4
+ rescue LoadError
5
5
  warn "Could not load 'omniauth'. Please ensure you have the omniauth gem >= 1.0.0 installed and listed in your Gemfile."
6
6
  raise
7
7
  end
@@ -2,21 +2,6 @@ module Devise
2
2
  module OmniAuth
3
3
  module UrlHelpers
4
4
  def self.define_helpers(mapping)
5
- return unless mapping.omniauthable?
6
-
7
- class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
8
- def #{mapping.name}_omniauth_authorize_path(provider, params = {})
9
- if Devise.omniauth_configs[provider.to_sym]
10
- script_name = request.env["SCRIPT_NAME"]
11
-
12
- path = "\#{script_name}/#{mapping.path}/auth/\#{provider}\".squeeze("/")
13
- path << '?' + params.to_param if params.present?
14
- path
15
- else
16
- raise ArgumentError, "Could not find omniauth provider \#{provider.inspect}"
17
- end
18
- end
19
- URL_HELPERS
20
5
  end
21
6
 
22
7
  def omniauth_authorize_path(resource_or_scope, *args)
@@ -1,4 +1,5 @@
1
1
  require "active_support/core_ext/object/try"
2
+ require "active_support/core_ext/hash/slice"
2
3
 
3
4
  module ActionDispatch::Routing
4
5
  class RouteSet #:nodoc:
@@ -236,7 +237,9 @@ module ActionDispatch::Routing
236
237
  end
237
238
  end
238
239
 
239
- # Allow you to add authentication request from the router:
240
+ # Allow you to add authentication request from the router.
241
+ # Takes an optional scope and block to provide constraints
242
+ # on the model instance itself.
240
243
  #
241
244
  # authenticate do
242
245
  # resources :post
@@ -246,9 +249,13 @@ module ActionDispatch::Routing
246
249
  # resources :users
247
250
  # end
248
251
  #
249
- def authenticate(scope=nil)
252
+ # authenticate :user, lambda {|u| u.role == "admin"} do
253
+ # root :to => "admin/dashboard#show"
254
+ # end
255
+ #
256
+ def authenticate(scope=nil, block=nil)
250
257
  constraint = lambda do |request|
251
- request.env["warden"].authenticate!(:scope => scope)
258
+ request.env["warden"].authenticate!(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
252
259
  end
253
260
 
254
261
  constraints(constraint) do
@@ -257,7 +264,8 @@ module ActionDispatch::Routing
257
264
  end
258
265
 
259
266
  # Allow you to route based on whether a scope is authenticated. You
260
- # can optionally specify which scope.
267
+ # can optionally specify which scope and a block. The block accepts
268
+ # a model and allows extra constraints to be done on the instance.
261
269
  #
262
270
  # authenticated :admin do
263
271
  # root :to => 'admin/dashboard#show'
@@ -267,11 +275,15 @@ module ActionDispatch::Routing
267
275
  # root :to => 'dashboard#show'
268
276
  # end
269
277
  #
278
+ # authenticated :user, lambda {|u| u.role == "admin"} do
279
+ # root :to => "admin/dashboard#show"
280
+ # end
281
+ #
270
282
  # root :to => 'landing#show'
271
283
  #
272
- def authenticated(scope=nil)
284
+ def authenticated(scope=nil, block=nil)
273
285
  constraint = lambda do |request|
274
- request.env["warden"].authenticate? :scope => scope
286
+ request.env["warden"].authenticate?(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
275
287
  end
276
288
 
277
289
  constraints(constraint) do
@@ -367,40 +379,62 @@ module ActionDispatch::Routing
367
379
  :cancel => mapping.path_names[:cancel]
368
380
  }
369
381
 
370
- resource :registration, :only => [:new, :create, :edit, :update, :destroy], :path => mapping.path_names[:registration],
371
- :path_names => path_names, :controller => controllers[:registrations] do
382
+ options = {
383
+ :only => [:new, :create, :edit, :update, :destroy],
384
+ :path => mapping.path_names[:registration],
385
+ :path_names => path_names,
386
+ :controller => controllers[:registrations]
387
+ }
388
+
389
+ resource :registration, options do
372
390
  get :cancel
373
391
  end
374
392
  end
375
393
 
376
394
  def devise_omniauth_callback(mapping, controllers) #:nodoc:
377
395
  path, @scope[:path] = @scope[:path], nil
378
- path_prefix = "/#{mapping.path}/auth".squeeze("/")
396
+ path_prefix = Devise.omniauth_path_prefix || "/#{mapping.path}/auth".squeeze("/")
397
+ set_omniauth_path_prefix!(path_prefix)
379
398
 
380
- if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
381
- raise "Wrong OmniAuth configuration. If you are getting this exception, it means that either:\n\n" \
382
- "1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one\n" \
383
- "2) You are setting :omniauthable in more than one model\n" \
384
- "3) You changed your Devise routes/OmniAuth setting and haven't restarted your server"
385
- else
386
- ::OmniAuth.config.path_prefix = path_prefix
387
- end
399
+ providers = Regexp.union(mapping.to.omniauth_providers.map(&:to_s))
388
400
 
389
- match "#{path_prefix}/:action/callback", :constraints => { :action => Regexp.union(mapping.to.omniauth_providers.map(&:to_s)) },
390
- :to => controllers[:omniauth_callbacks], :as => :omniauth_callback
401
+ match "#{path_prefix}/:provider",
402
+ :constraints => { :provider => providers },
403
+ :to => "#{controllers[:omniauth_callbacks]}#passthru",
404
+ :as => :omniauth_authorize
405
+
406
+ match "#{path_prefix}/:action/callback",
407
+ :constraints => { :action => providers },
408
+ :to => controllers[:omniauth_callbacks],
409
+ :as => :omniauth_callback
391
410
  ensure
392
411
  @scope[:path] = path
393
412
  end
394
413
 
414
+ DEVISE_SCOPE_KEYS = [:as, :path, :module, :constraints, :defaults, :options]
415
+
395
416
  def with_devise_exclusive_scope(new_path, new_as, options) #:nodoc:
396
- old_as, old_path, old_module, old_constraints, old_defaults, old_options =
397
- *@scope.values_at(:as, :path, :module, :constraints, :defaults, :options)
398
- @scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults], @scope[:options] =
399
- new_as, new_path, nil, *options.values_at(:constraints, :defaults, :options)
417
+ old = {}
418
+ DEVISE_SCOPE_KEYS.each { |k| old[k] = @scope[k] }
419
+
420
+ new = { :as => new_as, :path => new_path, :module => nil }
421
+ new.merge!(options.slice(:constraints, :defaults, :options))
422
+
423
+ @scope.merge!(new)
400
424
  yield
401
425
  ensure
402
- @scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults], @scope[:options] =
403
- old_as, old_path, old_module, old_constraints, old_defaults, old_options
426
+ @scope.merge!(old)
427
+ end
428
+
429
+ def set_omniauth_path_prefix!(path_prefix) #:nodoc:
430
+ if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
431
+ raise "Wrong OmniAuth configuration. If you are getting this exception, it means that either:\n\n" \
432
+ "1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one\n" \
433
+ "2) You are setting :omniauthable in more than one model\n" \
434
+ "3) You changed your Devise routes/OmniAuth setting and haven't restarted your server"
435
+ else
436
+ ::OmniAuth.config.path_prefix = path_prefix
437
+ end
404
438
  end
405
439
 
406
440
  def raise_no_devise_method_error!(klass) #:nodoc: