devise 1.1.3 → 1.2.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.
Files changed (157) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.rdoc +94 -0
  4. data/Gemfile +24 -13
  5. data/Gemfile.lock +119 -75
  6. data/MIT-LICENSE +1 -1
  7. data/README.rdoc +144 -101
  8. data/Rakefile +3 -24
  9. data/app/controllers/devise/confirmations_controller.rb +1 -1
  10. data/app/controllers/devise/omniauth_callbacks_controller.rb +26 -0
  11. data/app/controllers/devise/passwords_controller.rb +1 -1
  12. data/app/controllers/devise/registrations_controller.rb +60 -7
  13. data/app/controllers/devise/sessions_controller.rb +6 -4
  14. data/app/controllers/devise/unlocks_controller.rb +1 -1
  15. data/app/helpers/devise_helper.rb +10 -2
  16. data/app/mailers/devise/mailer.rb +27 -10
  17. data/app/views/devise/confirmations/new.html.erb +1 -1
  18. data/app/views/devise/passwords/edit.html.erb +2 -2
  19. data/app/views/devise/passwords/new.html.erb +1 -1
  20. data/app/views/devise/registrations/edit.html.erb +1 -1
  21. data/app/views/devise/registrations/new.html.erb +1 -1
  22. data/app/views/devise/sessions/new.html.erb +1 -1
  23. data/app/views/devise/shared/_links.erb +6 -0
  24. data/app/views/devise/unlocks/new.html.erb +1 -1
  25. data/config/locales/en.yml +11 -2
  26. data/devise.gemspec +25 -0
  27. data/lib/devise/controllers/helpers.rb +119 -116
  28. data/lib/devise/controllers/internal_helpers.rb +29 -8
  29. data/lib/devise/controllers/rememberable.rb +52 -0
  30. data/lib/devise/controllers/scoped_views.rb +4 -6
  31. data/lib/devise/controllers/url_helpers.rb +3 -5
  32. data/lib/devise/encryptors/authlogic_sha512.rb +1 -1
  33. data/lib/devise/encryptors/base.rb +1 -1
  34. data/lib/devise/encryptors/restful_authentication_sha1.rb +4 -4
  35. data/lib/devise/failure_app.rb +46 -10
  36. data/lib/devise/hooks/activatable.rb +2 -2
  37. data/lib/devise/hooks/forgetable.rb +1 -3
  38. data/lib/devise/hooks/rememberable.rb +5 -42
  39. data/lib/devise/hooks/timeoutable.rb +1 -1
  40. data/lib/devise/mapping.rb +18 -7
  41. data/lib/devise/models/authenticatable.rb +73 -31
  42. data/lib/devise/models/confirmable.rb +16 -20
  43. data/lib/devise/models/database_authenticatable.rb +27 -37
  44. data/lib/devise/models/encryptable.rb +72 -0
  45. data/lib/devise/models/lockable.rb +27 -21
  46. data/lib/devise/models/omniauthable.rb +23 -0
  47. data/lib/devise/models/recoverable.rb +13 -3
  48. data/lib/devise/models/registerable.rb +13 -0
  49. data/lib/devise/models/rememberable.rb +39 -34
  50. data/lib/devise/models/timeoutable.rb +20 -3
  51. data/lib/devise/models/token_authenticatable.rb +22 -10
  52. data/lib/devise/models/validatable.rb +16 -4
  53. data/lib/devise/models.rb +4 -16
  54. data/lib/devise/modules.rb +15 -8
  55. data/lib/devise/omniauth/config.rb +18 -0
  56. data/lib/devise/omniauth/url_helpers.rb +33 -0
  57. data/lib/devise/omniauth.rb +32 -0
  58. data/lib/devise/orm/active_record.rb +2 -0
  59. data/lib/devise/orm/mongoid.rb +4 -2
  60. data/lib/devise/rails/routes.rb +67 -20
  61. data/lib/devise/rails/warden_compat.rb +101 -15
  62. data/lib/devise/rails.rb +33 -44
  63. data/lib/devise/schema.rb +16 -16
  64. data/lib/devise/strategies/authenticatable.rb +48 -7
  65. data/lib/devise/strategies/database_authenticatable.rb +1 -1
  66. data/lib/devise/strategies/rememberable.rb +6 -5
  67. data/lib/devise/strategies/token_authenticatable.rb +6 -2
  68. data/lib/devise/test_helpers.rb +13 -3
  69. data/lib/devise/version.rb +1 -1
  70. data/lib/devise.rb +162 -50
  71. data/lib/generators/active_record/devise_generator.rb +2 -2
  72. data/lib/generators/active_record/templates/migration.rb +2 -0
  73. data/lib/generators/devise/devise_generator.rb +3 -1
  74. data/lib/generators/devise/orm_helpers.rb +1 -1
  75. data/lib/generators/devise/views_generator.rb +8 -45
  76. data/lib/generators/mongoid/devise_generator.rb +2 -2
  77. data/lib/generators/templates/devise.rb +82 -39
  78. data/test/controllers/helpers_test.rb +78 -72
  79. data/test/controllers/internal_helpers_test.rb +29 -8
  80. data/test/controllers/url_helpers_test.rb +2 -1
  81. data/test/devise_test.rb +10 -0
  82. data/test/failure_app_test.rb +86 -22
  83. data/test/generators/active_record_generator_test.rb +24 -0
  84. data/test/generators/devise_generator_test.rb +33 -0
  85. data/test/generators/install_generator_test.rb +13 -0
  86. data/test/generators/mongoid_generator_test.rb +22 -0
  87. data/test/generators/views_generator_test.rb +35 -0
  88. data/test/indifferent_hash.rb +33 -0
  89. data/test/integration/authenticatable_test.rb +165 -62
  90. data/test/integration/database_authenticatable_test.rb +22 -0
  91. data/test/integration/http_authenticatable_test.rb +12 -2
  92. data/test/integration/omniauthable_test.rb +138 -0
  93. data/test/integration/recoverable_test.rb +39 -20
  94. data/test/integration/registerable_test.rb +60 -4
  95. data/test/integration/rememberable_test.rb +72 -29
  96. data/test/integration/timeoutable_test.rb +10 -1
  97. data/test/integration/token_authenticatable_test.rb +55 -6
  98. data/test/mailers/confirmation_instructions_test.rb +4 -0
  99. data/test/mailers/reset_password_instructions_test.rb +4 -0
  100. data/test/mailers/unlock_instructions_test.rb +4 -0
  101. data/test/mapping_test.rb +37 -3
  102. data/test/models/confirmable_test.rb +32 -15
  103. data/test/models/database_authenticatable_test.rb +14 -71
  104. data/test/models/encryptable_test.rb +65 -0
  105. data/test/models/lockable_test.rb +48 -11
  106. data/test/models/recoverable_test.rb +28 -2
  107. data/test/models/rememberable_test.rb +186 -125
  108. data/test/models/token_authenticatable_test.rb +19 -1
  109. data/test/models_test.rb +12 -5
  110. data/test/omniauth/url_helpers_test.rb +54 -0
  111. data/test/orm/mongoid.rb +3 -2
  112. data/test/rails_app/Rakefile +10 -0
  113. data/test/rails_app/app/active_record/admin.rb +4 -1
  114. data/test/rails_app/app/active_record/user.rb +5 -4
  115. data/test/rails_app/app/controllers/{sessions_controller.rb → admins/sessions_controller.rb} +1 -1
  116. data/test/rails_app/app/controllers/application_controller.rb +0 -1
  117. data/test/rails_app/app/controllers/home_controller.rb +9 -0
  118. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
  119. data/test/rails_app/app/mongoid/admin.rb +4 -1
  120. data/test/rails_app/app/mongoid/shim.rb +16 -3
  121. data/test/rails_app/app/mongoid/user.rb +5 -5
  122. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  123. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  124. data/test/rails_app/app/views/home/index.html.erb +1 -0
  125. data/test/rails_app/app/views/home/private.html.erb +1 -0
  126. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  127. data/test/rails_app/app/views/users/index.html.erb +1 -0
  128. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  129. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  130. data/test/rails_app/config/application.rb +5 -0
  131. data/test/rails_app/config/boot.rb +2 -2
  132. data/test/rails_app/config/database.yml +18 -0
  133. data/test/rails_app/config/initializers/devise.rb +71 -31
  134. data/test/rails_app/config/routes.rb +14 -6
  135. data/test/rails_app/config.ru +4 -0
  136. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +21 -17
  137. data/test/rails_app/db/schema.rb +17 -51
  138. data/test/rails_app/lib/shared_admin.rb +9 -0
  139. data/test/rails_app/lib/shared_user.rb +23 -0
  140. data/test/rails_app/public/404.html +26 -0
  141. data/test/rails_app/public/422.html +26 -0
  142. data/test/rails_app/public/500.html +26 -0
  143. data/test/rails_app/public/favicon.ico +0 -0
  144. data/test/rails_app/script/rails +10 -0
  145. data/test/routes_test.rb +42 -9
  146. data/test/schema_test.rb +33 -0
  147. data/test/support/integration.rb +4 -4
  148. data/test/support/locale/en.yml +4 -0
  149. data/test/support/webrat/integrations/rails.rb +11 -19
  150. data/test/test_helper.rb +8 -2
  151. data/test/test_helpers_test.rb +64 -2
  152. metadata +106 -30
  153. data/TODO +0 -3
  154. data/lib/devise/encryptors/bcrypt.rb +0 -19
  155. data/lib/generators/devise_install_generator.rb +0 -4
  156. data/lib/generators/devise_views_generator.rb +0 -4
  157. data/test/support/test_silencer.rb +0 -5
data/lib/devise/models.rb CHANGED
@@ -2,7 +2,7 @@ module Devise
2
2
  module Models
3
3
  # Creates configuration values for Devise and for the given module.
4
4
  #
5
- # Devise::Models.config(Devise::Authenticable, :stretches, 10)
5
+ # Devise::Models.config(Devise::Authenticatable, :stretches, 10)
6
6
  #
7
7
  # The line above creates:
8
8
  #
@@ -47,21 +47,9 @@ module Devise
47
47
  def devise(*modules)
48
48
  include Devise::Models::Authenticatable
49
49
  options = modules.extract_options!
50
-
51
- if modules.delete(:authenticatable)
52
- ActiveSupport::Deprecation.warn ":authenticatable as module is deprecated. Please give :database_authenticatable instead.", caller
53
- modules << :database_authenticatable
54
- end
55
-
56
- if modules.delete(:activatable)
57
- ActiveSupport::Deprecation.warn ":activatable as module is deprecated. It's included in your model by default.", caller
58
- end
59
-
60
- if modules.delete(:http_authenticatable)
61
- ActiveSupport::Deprecation.warn ":http_authenticatable as module is deprecated and is on by default. Revert by setting :http_authenticatable => false.", caller
62
- end
63
-
64
- self.devise_modules += Devise::ALL & modules.map(&:to_sym).uniq
50
+ self.devise_modules += modules.map(&:to_sym).uniq.sort_by { |s|
51
+ Devise::ALL.index(s) || -1 # follow Devise::ALL order
52
+ }
65
53
 
66
54
  devise_modules_hook! do
67
55
  devise_modules.each { |m| include Devise::Models.const_get(m.to_s.classify) }
@@ -2,20 +2,27 @@ require 'active_support/core_ext/object/with_options'
2
2
 
3
3
  Devise.with_options :model => true do |d|
4
4
  # Strategies first
5
- d.with_options :strategy => true do |s|
6
- s.add_module :database_authenticatable, :controller => :sessions, :route => :session
7
- s.add_module :token_authenticatable, :controller => :sessions, :route => :session
5
+ d.with_options :strategy => true do |s|
6
+ routes = [nil, :new, :destroy]
7
+ s.add_module :database_authenticatable, :controller => :sessions, :route => { :session => routes }
8
+ s.add_module :token_authenticatable, :controller => :sessions, :route => { :session => routes }
8
9
  s.add_module :rememberable
9
10
  end
10
11
 
11
- # Misc after
12
- d.add_module :recoverable, :controller => :passwords, :route => :password
13
- d.add_module :registerable, :controller => :registrations, :route => :registration
12
+ # Other authentications
13
+ d.add_module :encryptable
14
+ d.add_module :omniauthable, :controller => :omniauth_callbacks, :route => :omniauth_callback
15
+
16
+ # Misc after
17
+ routes = [nil, :new, :edit]
18
+ d.add_module :recoverable, :controller => :passwords, :route => { :password => routes }
19
+ d.add_module :registerable, :controller => :registrations, :route => { :registration => (routes << :cancel) }
14
20
  d.add_module :validatable
15
21
 
16
22
  # The ones which can sign out after
17
- d.add_module :confirmable, :controller => :confirmations, :route => :confirmation
18
- d.add_module :lockable, :controller => :unlocks, :route => :unlock
23
+ routes = [nil, :new]
24
+ d.add_module :confirmable, :controller => :confirmations, :route => { :confirmation => routes }
25
+ d.add_module :lockable, :controller => :unlocks, :route => { :unlock => routes }
19
26
  d.add_module :timeoutable
20
27
 
21
28
  # Stats for last, so we make sure the user is really signed in
@@ -0,0 +1,18 @@
1
+ module Devise
2
+ module OmniAuth
3
+ class Config
4
+ attr_accessor :strategy
5
+ attr_reader :args
6
+
7
+ def initialize(provider, args)
8
+ @provider = provider
9
+ @args = args
10
+ @strategy = nil
11
+ end
12
+
13
+ def strategy_class
14
+ ::OmniAuth::Strategies.const_get("#{::OmniAuth::Utils.camelize(@provider.to_s)}")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ module Devise
2
+ module OmniAuth
3
+ module UrlHelpers
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
+ end
21
+
22
+ def omniauth_authorize_path(resource_or_scope, *args)
23
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
24
+ send("#{scope}_omniauth_authorize_path", *args)
25
+ end
26
+
27
+ def omniauth_callback_path(resource_or_scope, *args)
28
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
29
+ send("#{scope}_omniauth_callback_path", *args)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ begin
2
+ require "omniauth/core"
3
+ rescue LoadError => e
4
+ warn "Could not load 'omniauth/core'. Please ensure you have the oa-core gem installed and listed in your Gemfile."
5
+ raise
6
+ end
7
+
8
+ unless OmniAuth.config.respond_to? :test_mode
9
+ raise "You are using an old OmniAuth version, please ensure you have 0.2.0.beta version or later installed."
10
+ end
11
+
12
+ # Clean up the default path_prefix. It will be automatically set by Devise.
13
+ OmniAuth.config.path_prefix = nil
14
+
15
+ OmniAuth.config.on_failure = Proc.new do |env|
16
+ env['devise.mapping'] = Devise::Mapping.find_by_path!(env['PATH_INFO'], :path)
17
+ controller_klass = "#{env['devise.mapping'].controllers[:omniauth_callbacks].camelize}Controller"
18
+ controller_klass.constantize.action(:failure).call(env)
19
+ end
20
+
21
+ module Devise
22
+ module OmniAuth
23
+ autoload :Config, "devise/omniauth/config"
24
+ autoload :UrlHelpers, "devise/omniauth/url_helpers"
25
+ autoload :TestHelpers, "devise/omniauth/test_helpers"
26
+
27
+ class << self
28
+ delegate :short_circuit_authorizers!, :unshort_circuit_authorizers!,
29
+ :test_mode!, :stub!, :reset_stubs!, :to => "Devise::OmniAuth::TestHelpers"
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,5 @@
1
+ require 'orm_adapter/adapters/active_record'
2
+
1
3
  module Devise
2
4
  module Orm
3
5
  # This module contains some helpers and handle schema (migrations):
@@ -1,3 +1,5 @@
1
+ require 'orm_adapter/adapters/mongoid'
2
+
1
3
  module Devise
2
4
  module Orm
3
5
  module Mongoid
@@ -16,7 +18,7 @@ module Devise
16
18
  # Tell how to apply schema methods
17
19
  def apply_devise_schema(name, type, options={})
18
20
  type = Time if type == DateTime
19
- field name, { :type => type }.merge(options)
21
+ field name, { :type => type }.merge!(options)
20
22
  end
21
23
  end
22
24
  end
@@ -26,4 +28,4 @@ end
26
28
  Mongoid::Document::ClassMethods.class_eval do
27
29
  include Devise::Models
28
30
  include Devise::Orm::Mongoid::Hook
29
- end
31
+ end
@@ -5,7 +5,6 @@ module ActionDispatch::Routing
5
5
  def finalize_with_devise!
6
6
  finalize_without_devise!
7
7
  Devise.configure_warden!
8
- ActionController::Base.send :include, Devise::Controllers::Helpers
9
8
  end
10
9
  alias_method_chain :finalize!, :devise
11
10
  end
@@ -70,6 +69,13 @@ module ActionDispatch::Routing
70
69
  #
71
70
  # devise_for :users, :controllers => { :sessions => "users/sessions" }
72
71
  #
72
+ # * :sign_out_via => the HTTP method(s) accepted for the :sign_out action (default: :get),
73
+ # if you wish to restrict this to accept only :post or :delete requests you should do:
74
+ #
75
+ # devise_for :users, :sign_out_via => [ :post, :delete ]
76
+ #
77
+ # You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
78
+ #
73
79
  # * :module => the namespace to find controlers. By default, devise will access devise/sessions,
74
80
  # devise/registrations and so on. If you want to namespace all at once, use module:
75
81
  #
@@ -85,6 +91,10 @@ module ActionDispatch::Routing
85
91
  # Will use publisher/sessions controller instead of devise/sessions controller. You can revert
86
92
  # this by providing the :module option to devise_for.
87
93
  #
94
+ # Also pay attention that when you use a namespace it will affect all the helpers and methods for controllers
95
+ # and views. For example, using the above setup you'll end with following methods:
96
+ # current_publisher_account, authenticate_publisher_account!, pusblisher_account_signed_in, etc.
97
+ #
88
98
  # * :skip => tell which controller you want to skip routes from being created:
89
99
  #
90
100
  # devise_for :users, :skip => :sessions
@@ -113,19 +123,33 @@ module ActionDispatch::Routing
113
123
  # end
114
124
  # end
115
125
  #
126
+ # ==== Adding custom actions to override controllers
127
+ #
128
+ # You can pass a block to devise_for that will add any routes defined in the block to Devise's
129
+ # list of known actions. This is important if you add a custom action to a controller that
130
+ # overrides an out of the box Devise controller.
131
+ # For example:
132
+ #
133
+ # class RegistrationsController < Devise::RegistrationsController
134
+ # def update
135
+ # # do something different here
136
+ # end
137
+ #
138
+ # def deactivate
139
+ # # not a standard action
140
+ # # deactivate code here
141
+ # end
142
+ # end
143
+ #
144
+ # In order to get Devise to recognize the deactivate action, your devise_for entry should look like this,
145
+ #
146
+ # devise_for :owners, :controllers => { :registrations => "registrations" } do
147
+ # post "deactivate", :to => "registrations#deactivate", :as => "deactivate_registration"
148
+ # end
149
+ #
116
150
  def devise_for(*resources)
117
151
  options = resources.extract_options!
118
152
 
119
- if as = options.delete(:as)
120
- ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
121
- options[:path] ||= as
122
- end
123
-
124
- if scope = options.delete(:scope)
125
- ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
126
- options[:singular] ||= scope
127
- end
128
-
129
153
  options[:as] ||= @scope[:as] if @scope[:as].present?
130
154
  options[:module] ||= @scope[:module] if @scope[:module].present?
131
155
  options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
@@ -154,7 +178,7 @@ module ActionDispatch::Routing
154
178
  devise_scope mapping.name do
155
179
  yield if block_given?
156
180
  with_devise_exclusive_scope mapping.fullpath, mapping.name do
157
- routes.each { |mod| send(:"devise_#{mod}", mapping, mapping.controllers) }
181
+ routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
158
182
  end
159
183
  end
160
184
  end
@@ -203,22 +227,22 @@ module ActionDispatch::Routing
203
227
 
204
228
  def devise_session(mapping, controllers) #:nodoc:
205
229
  resource :session, :only => [], :controller => controllers[:sessions], :path => "" do
206
- get :new, :path => mapping.path_names[:sign_in], :as => "new"
207
- post :create, :path => mapping.path_names[:sign_in]
208
- get :destroy, :path => mapping.path_names[:sign_out], :as => "destroy"
230
+ get :new, :path => mapping.path_names[:sign_in], :as => "new"
231
+ post :create, :path => mapping.path_names[:sign_in]
232
+ match :destroy, :path => mapping.path_names[:sign_out], :as => "destroy", :via => mapping.sign_out_via
209
233
  end
210
234
  end
211
-
235
+
212
236
  def devise_password(mapping, controllers) #:nodoc:
213
237
  resource :password, :only => [:new, :create, :edit, :update],
214
238
  :path => mapping.path_names[:password], :controller => controllers[:passwords]
215
239
  end
216
-
240
+
217
241
  def devise_confirmation(mapping, controllers) #:nodoc:
218
242
  resource :confirmation, :only => [:new, :create, :show],
219
243
  :path => mapping.path_names[:confirmation], :controller => controllers[:confirmations]
220
244
  end
221
-
245
+
222
246
  def devise_unlock(mapping, controllers) #:nodoc:
223
247
  if mapping.to.unlock_strategy_enabled?(:email)
224
248
  resource :unlock, :only => [:new, :create, :show],
@@ -227,8 +251,31 @@ module ActionDispatch::Routing
227
251
  end
228
252
 
229
253
  def devise_registration(mapping, controllers) #:nodoc:
230
- resource :registration, :only => [:new, :create, :edit, :update, :destroy], :path => mapping.path_names[:registration],
231
- :path_names => { :new => mapping.path_names[:sign_up] }, :controller => controllers[:registrations]
254
+ path_names = {
255
+ :new => mapping.path_names[:sign_up],
256
+ :cancel => mapping.path_names[:cancel]
257
+ }
258
+
259
+ resource :registration, :except => :show, :path => mapping.path_names[:registration],
260
+ :path_names => path_names, :controller => controllers[:registrations] do
261
+ get :cancel
262
+ end
263
+ end
264
+
265
+ def devise_omniauth_callback(mapping, controllers) #:nodoc:
266
+ path, @scope[:path] = @scope[:path], nil
267
+ path_prefix = "/#{mapping.path}/auth".squeeze("/")
268
+
269
+ if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
270
+ warn "[DEVISE] You can only add :omniauthable behavior to one model."
271
+ else
272
+ ::OmniAuth.config.path_prefix = path_prefix
273
+ end
274
+
275
+ match "#{path_prefix}/:action/callback", :action => Regexp.union(mapping.to.omniauth_providers.map(&:to_s)),
276
+ :to => controllers[:omniauth_callbacks], :as => :omniauth_callback
277
+ ensure
278
+ @scope[:path] = path
232
279
  end
233
280
 
234
281
  def with_devise_exclusive_scope(new_path, new_as) #:nodoc:
@@ -3,9 +3,9 @@ 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
7
  def reset_session!
7
- raw_session.inspect # why do I have to inspect it to get it to clear?
8
- raw_session.clear
8
+ request.reset_session
9
9
  end
10
10
 
11
11
  def cookies
@@ -15,25 +15,111 @@ end
15
15
 
16
16
  class Warden::SessionSerializer
17
17
  def serialize(record)
18
- [record.class.name, record.id]
18
+ [record.class.name, record.to_key, record.authenticatable_salt]
19
19
  end
20
20
 
21
21
  def deserialize(keys)
22
- klass, id = keys
23
-
24
- if klass.is_a?(Class)
22
+ if keys.size == 2
25
23
  raise "Devise changed how it stores objects in session. If you are seeing this message, " <<
26
- "you can fix it by changing one character in your cookie secret, forcing all previous " <<
27
- "cookies to expire, or cleaning up your database sessions if you are using a db store."
24
+ "you can fix it by changing one character in your cookie secret or cleaning up your " <<
25
+ "database sessions if you are using a db store."
26
+ end
27
+
28
+ klass, id, salt = keys
29
+
30
+ begin
31
+ record = klass.constantize.to_adapter.get(id)
32
+ record if record && record.authenticatable_salt == salt
33
+ rescue NameError => e
34
+ if e.message =~ /uninitialized constant/
35
+ Rails.logger.debug "[Devise] Trying to deserialize invalid class #{klass}"
36
+ nil
37
+ else
38
+ raise
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ unless Devise.rack_session?
45
+ # We cannot use Rails Indifferent Hash because it messes up the flash object.
46
+ class Devise::IndifferentHash < Hash
47
+ alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
48
+ alias_method :regular_update, :update unless method_defined?(:regular_update)
49
+
50
+ def [](key)
51
+ super(convert_key(key))
52
+ end
53
+
54
+ def []=(key, value)
55
+ regular_writer(convert_key(key), value)
56
+ end
57
+
58
+ alias_method :store, :[]=
59
+
60
+ def update(other_hash)
61
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), value) }
62
+ self
63
+ end
64
+
65
+ alias_method :merge!, :update
66
+
67
+ def key?(key)
68
+ super(convert_key(key))
69
+ end
70
+
71
+ alias_method :include?, :key?
72
+ alias_method :has_key?, :key?
73
+ alias_method :member?, :key?
74
+
75
+ def fetch(key, *extras)
76
+ super(convert_key(key), *extras)
77
+ end
78
+
79
+ def values_at(*indices)
80
+ indices.collect {|key| self[convert_key(key)]}
81
+ end
82
+
83
+ def merge(hash)
84
+ self.dup.update(hash)
85
+ end
86
+
87
+ def delete(key)
88
+ super(convert_key(key))
89
+ end
90
+
91
+ def stringify_keys!; self end
92
+ def stringify_keys; dup end
93
+
94
+ undef :symbolize_keys!
95
+ def symbolize_keys; to_hash.symbolize_keys end
96
+
97
+ def to_options!; self end
98
+ def to_hash; Hash.new.update(self) end
99
+
100
+ protected
101
+
102
+ def convert_key(key)
103
+ key.kind_of?(Symbol) ? key.to_s : key
28
104
  end
105
+ end
106
+
107
+ class ActionDispatch::Request
108
+ def reset_session
109
+ session.destroy if session && session.respond_to?(:destroy)
110
+ self.session = {}
111
+ @env['action_dispatch.request.flash_hash'] = nil
112
+ end
113
+ end
29
114
 
30
- klass.constantize.find(:first, :conditions => { :id => id })
31
- rescue NameError => e
32
- if e.message =~ /uninitialized constant/
33
- Rails.logger.debug "Trying to deserialize invalid class #{klass}"
34
- nil
35
- else
36
- raise
115
+ Warden::Manager.after_set_user :event => [:set_user, :authentication] do |record, warden, options|
116
+ if options[:scope] && warden.authenticated?(options[:scope])
117
+ request, flash = warden.request, warden.env['action_dispatch.request.flash_hash']
118
+ backup = request.session.to_hash
119
+ backup.delete("session_id")
120
+ request.reset_session
121
+ warden.env['action_dispatch.request.flash_hash'] = flash
122
+ request.session = Devise::IndifferentHash.new.update(backup)
37
123
  end
38
124
  end
39
125
  end
data/lib/devise/rails.rb CHANGED
@@ -1,14 +1,11 @@
1
1
  require 'devise/rails/routes'
2
2
  require 'devise/rails/warden_compat'
3
3
 
4
- # Include UrlHelpers in ActionController and ActionView as soon as they are loaded.
5
- ActiveSupport.on_load(:action_controller) { include Devise::Controllers::UrlHelpers }
6
- ActiveSupport.on_load(:action_view) { include Devise::Controllers::UrlHelpers }
7
-
8
4
  module Devise
9
5
  class Engine < ::Rails::Engine
10
6
  config.devise = Devise
11
7
 
8
+ # Initialize Warden and copy its configurations.
12
9
  config.app_middleware.use Warden::Manager do |config|
13
10
  Devise.warden_config = config
14
11
  end
@@ -16,54 +13,46 @@ module Devise
16
13
  # Force routes to be loaded if we are doing any eager load.
17
14
  config.before_eager_load { |app| app.reload_routes! }
18
15
 
19
- config.after_initialize do
20
- Devise.encryptor ||= begin
21
- warn "[WARNING] config.encryptor is not set in your config/initializers/devise.rb. " \
22
- "Devise will then set it to :bcrypt. If you were using the previous default " \
23
- "encryptor, please add config.encryptor = :sha1 to your configuration file." if Devise.mailer_sender
24
- :bcrypt
25
- end
16
+ initializer "devise.url_helpers" do
17
+ Devise.include_helpers(Devise::Controllers)
26
18
  end
27
19
 
28
- initializer "devise.add_filters" do |app|
29
- app.config.filter_parameters += [:password, :password_confirmation]
30
- app.config.filter_parameters.uniq
20
+ initializer "devise.navigationals" do
21
+ formats = Devise.navigational_formats
22
+ if formats.include?(:"*/*") && formats.exclude?("*/*")
23
+ puts "[DEVISE] We see the symbol :\"*/*\" in the navigational formats in your initializer " \
24
+ "but not the string \"*/*\". Due to changes in latest Rails, please include the latter."
25
+ end
31
26
  end
32
27
 
33
- unless Rails.env.production?
34
- config.after_initialize do
35
- actions = [:confirmation_instructions, :reset_password_instructions, :unlock_instructions]
36
-
37
- translations = begin
38
- I18n.t("devise.mailer", :raise => true).map { |k, v| k if v.is_a?(String) }.compact
39
- rescue Exception => e # Do not care if something fails
40
- []
41
- end
42
-
43
- keys = actions & translations
44
-
45
- keys.each do |key|
46
- ActiveSupport::Deprecation.warn "The I18n message 'devise.mailer.#{key}' is deprecated. " \
47
- "Please use 'devise.mailer.#{key}.subject' instead."
28
+ initializer "devise.omniauth" do |app|
29
+ Devise.omniauth_configs.each do |provider, config|
30
+ app.middleware.use config.strategy_class, *config.args do |strategy|
31
+ config.strategy = strategy
48
32
  end
49
33
  end
50
34
 
51
- config.after_initialize do
52
- flash = [:unauthenticated, :unconfirmed, :invalid, :invalid_token, :timeout, :inactive, :locked]
53
-
54
- translations = begin
55
- I18n.t("devise.sessions", :raise => true).keys
56
- rescue Exception => e # Do not care if something fails
57
- []
58
- end
59
-
60
- keys = flash & translations
35
+ if Devise.omniauth_configs.any?
36
+ Devise.include_helpers(Devise::OmniAuth)
37
+ end
38
+ end
61
39
 
62
- if keys.any?
63
- ActiveSupport::Deprecation.warn "The following I18n messages in 'devise.sessions' " \
64
- "are deprecated: #{keys.to_sentence}. Please move them to 'devise.failure' instead."
65
- end
40
+ initializer "devise.encryptor_check" do
41
+ case Devise.encryptor
42
+ when :bcrypt
43
+ puts "[DEVISE] From version 1.2, there is no need to set your encryptor to bcrypt " \
44
+ "since encryptors are only enabled if you include :encryptable in your models. " \
45
+ "With this change, we can integrate better with bcrypt and get rid of the " \
46
+ "password_salt column (since bcrypt stores the salt with password). " \
47
+ "Please comment config.encryptor in your initializer to get rid of this warning."
48
+ when nil
49
+ # Nothing to say
50
+ else
51
+ puts "[DEVISE] You are using #{Devise.encryptor} as encryptor. From version 1.2, " \
52
+ "you need to explicitly add `devise :encryptable, :encryptor => :#{Devise.encryptor}` " \
53
+ "to your models and comment the current value in the config/initializers/devise.rb. " \
54
+ "You must also add t.encryptable to your existing migrations."
66
55
  end
67
56
  end
68
57
  end
69
- end
58
+ end
data/lib/devise/schema.rb CHANGED
@@ -3,12 +3,7 @@ module Devise
3
3
  # and overwrite the apply_schema method.
4
4
  module Schema
5
5
 
6
- def authenticatable(*args)
7
- ActiveSupport::Deprecation.warn "t.authenticatable in migrations is deprecated. Please use t.database_authenticatable instead.", caller
8
- database_authenticatable(*args)
9
- end
10
-
11
- # Creates email, encrypted_password and password_salt.
6
+ # Creates email when enabled (on by default), encrypted_password and password_salt.
12
7
  #
13
8
  # == Options
14
9
  # * :null - When true, allow columns to be null.
@@ -20,18 +15,19 @@ module Devise
20
15
  def database_authenticatable(options={})
21
16
  null = options[:null] || false
22
17
  default = options.key?(:default) ? options[:default] : ("" if null == false)
18
+ include_email = !self.respond_to?(:authentication_keys) || self.authentication_keys.include?(:email)
23
19
 
24
- if options.delete(:encryptor)
25
- ActiveSupport::Deprecation.warn ":encryptor as option is deprecated, simply remove it."
26
- end
27
-
28
- apply_devise_schema :email, String, :null => null, :default => default
20
+ apply_devise_schema :email, String, :null => null, :default => default if include_email
29
21
  apply_devise_schema :encrypted_password, String, :null => null, :default => default, :limit => 128
30
- apply_devise_schema :password_salt, String, :null => null, :default => default
31
- end
22
+ end
23
+
24
+ # Creates password salt for encryption support.
25
+ def encryptable
26
+ apply_devise_schema :password_salt, String
27
+ end
32
28
 
33
29
  # Creates authentication_token.
34
- def token_authenticatable(options={})
30
+ def token_authenticatable
35
31
  apply_devise_schema :authentication_token, String
36
32
  end
37
33
 
@@ -48,8 +44,12 @@ module Devise
48
44
  end
49
45
 
50
46
  # Creates remember_token and remember_created_at.
51
- def rememberable
52
- apply_devise_schema :remember_token, String
47
+ #
48
+ # == Options
49
+ # * :use_salt - When true, does not create a remember_token and use password_salt instead.
50
+ def rememberable(options={})
51
+ use_salt = options.fetch(:use_salt, Devise.use_salt_as_remember_token)
52
+ apply_devise_schema :remember_token, String unless use_salt
53
53
  apply_devise_schema :remember_created_at, DateTime
54
54
  end
55
55