devise-edge 1.2.rc

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 (161) hide show
  1. data/CHANGELOG.rdoc +500 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +335 -0
  4. data/app/controllers/devise/confirmations_controller.rb +33 -0
  5. data/app/controllers/devise/oauth_callbacks_controller.rb +4 -0
  6. data/app/controllers/devise/passwords_controller.rb +41 -0
  7. data/app/controllers/devise/registrations_controller.rb +75 -0
  8. data/app/controllers/devise/sessions_controller.rb +23 -0
  9. data/app/controllers/devise/unlocks_controller.rb +34 -0
  10. data/app/helpers/devise_helper.rb +17 -0
  11. data/app/mailers/devise/mailer.rb +88 -0
  12. data/app/views/devise/confirmations/new.html.erb +12 -0
  13. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  14. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  15. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  16. data/app/views/devise/passwords/edit.html.erb +16 -0
  17. data/app/views/devise/passwords/new.html.erb +12 -0
  18. data/app/views/devise/registrations/edit.html.erb +25 -0
  19. data/app/views/devise/registrations/new.html.erb +18 -0
  20. data/app/views/devise/sessions/new.html.erb +17 -0
  21. data/app/views/devise/shared/_links.erb +25 -0
  22. data/app/views/devise/unlocks/new.html.erb +12 -0
  23. data/config/locales/en.yml +42 -0
  24. data/lib/devise.rb +371 -0
  25. data/lib/devise/controllers/helpers.rb +261 -0
  26. data/lib/devise/controllers/internal_helpers.rb +113 -0
  27. data/lib/devise/controllers/scoped_views.rb +33 -0
  28. data/lib/devise/controllers/url_helpers.rb +39 -0
  29. data/lib/devise/encryptors/authlogic_sha512.rb +19 -0
  30. data/lib/devise/encryptors/base.rb +20 -0
  31. data/lib/devise/encryptors/clearance_sha1.rb +17 -0
  32. data/lib/devise/encryptors/restful_authentication_sha1.rb +22 -0
  33. data/lib/devise/encryptors/sha1.rb +25 -0
  34. data/lib/devise/encryptors/sha512.rb +25 -0
  35. data/lib/devise/failure_app.rb +126 -0
  36. data/lib/devise/hooks/activatable.rb +11 -0
  37. data/lib/devise/hooks/forgetable.rb +12 -0
  38. data/lib/devise/hooks/rememberable.rb +45 -0
  39. data/lib/devise/hooks/timeoutable.rb +22 -0
  40. data/lib/devise/hooks/trackable.rb +9 -0
  41. data/lib/devise/mapping.rb +105 -0
  42. data/lib/devise/models.rb +66 -0
  43. data/lib/devise/models/authenticatable.rb +143 -0
  44. data/lib/devise/models/confirmable.rb +160 -0
  45. data/lib/devise/models/database_authenticatable.rb +94 -0
  46. data/lib/devise/models/encryptable.rb +65 -0
  47. data/lib/devise/models/lockable.rb +168 -0
  48. data/lib/devise/models/oauthable.rb +49 -0
  49. data/lib/devise/models/recoverable.rb +83 -0
  50. data/lib/devise/models/registerable.rb +21 -0
  51. data/lib/devise/models/rememberable.rb +122 -0
  52. data/lib/devise/models/timeoutable.rb +33 -0
  53. data/lib/devise/models/token_authenticatable.rb +72 -0
  54. data/lib/devise/models/trackable.rb +30 -0
  55. data/lib/devise/models/validatable.rb +60 -0
  56. data/lib/devise/modules.rb +30 -0
  57. data/lib/devise/oauth.rb +41 -0
  58. data/lib/devise/oauth/config.rb +33 -0
  59. data/lib/devise/oauth/helpers.rb +18 -0
  60. data/lib/devise/oauth/internal_helpers.rb +182 -0
  61. data/lib/devise/oauth/test_helpers.rb +29 -0
  62. data/lib/devise/oauth/url_helpers.rb +35 -0
  63. data/lib/devise/orm/active_record.rb +36 -0
  64. data/lib/devise/orm/mongo_mapper.rb +46 -0
  65. data/lib/devise/orm/mongoid.rb +29 -0
  66. data/lib/devise/path_checker.rb +18 -0
  67. data/lib/devise/rails.rb +67 -0
  68. data/lib/devise/rails/routes.rb +260 -0
  69. data/lib/devise/rails/warden_compat.rb +42 -0
  70. data/lib/devise/schema.rb +96 -0
  71. data/lib/devise/strategies/authenticatable.rb +150 -0
  72. data/lib/devise/strategies/base.rb +15 -0
  73. data/lib/devise/strategies/database_authenticatable.rb +21 -0
  74. data/lib/devise/strategies/rememberable.rb +51 -0
  75. data/lib/devise/strategies/token_authenticatable.rb +53 -0
  76. data/lib/devise/test_helpers.rb +100 -0
  77. data/lib/devise/version.rb +3 -0
  78. data/lib/generators/active_record/devise_generator.rb +28 -0
  79. data/lib/generators/active_record/templates/migration.rb +30 -0
  80. data/lib/generators/devise/devise_generator.rb +17 -0
  81. data/lib/generators/devise/install_generator.rb +24 -0
  82. data/lib/generators/devise/orm_helpers.rb +24 -0
  83. data/lib/generators/devise/views_generator.rb +63 -0
  84. data/lib/generators/mongoid/devise_generator.rb +17 -0
  85. data/lib/generators/templates/README +25 -0
  86. data/lib/generators/templates/devise.rb +168 -0
  87. data/test/controllers/helpers_test.rb +220 -0
  88. data/test/controllers/internal_helpers_test.rb +56 -0
  89. data/test/controllers/url_helpers_test.rb +59 -0
  90. data/test/devise_test.rb +65 -0
  91. data/test/encryptors_test.rb +30 -0
  92. data/test/failure_app_test.rb +148 -0
  93. data/test/integration/authenticatable_test.rb +424 -0
  94. data/test/integration/confirmable_test.rb +104 -0
  95. data/test/integration/database_authenticatable_test.rb +38 -0
  96. data/test/integration/http_authenticatable_test.rb +64 -0
  97. data/test/integration/lockable_test.rb +109 -0
  98. data/test/integration/oauthable_test.rb +258 -0
  99. data/test/integration/recoverable_test.rb +141 -0
  100. data/test/integration/registerable_test.rb +179 -0
  101. data/test/integration/rememberable_test.rb +179 -0
  102. data/test/integration/timeoutable_test.rb +80 -0
  103. data/test/integration/token_authenticatable_test.rb +99 -0
  104. data/test/integration/trackable_test.rb +64 -0
  105. data/test/mailers/confirmation_instructions_test.rb +84 -0
  106. data/test/mailers/reset_password_instructions_test.rb +72 -0
  107. data/test/mailers/unlock_instructions_test.rb +66 -0
  108. data/test/mapping_test.rb +95 -0
  109. data/test/models/confirmable_test.rb +221 -0
  110. data/test/models/database_authenticatable_test.rb +82 -0
  111. data/test/models/encryptable_test.rb +65 -0
  112. data/test/models/lockable_test.rb +204 -0
  113. data/test/models/oauthable_test.rb +21 -0
  114. data/test/models/recoverable_test.rb +155 -0
  115. data/test/models/rememberable_test.rb +271 -0
  116. data/test/models/timeoutable_test.rb +28 -0
  117. data/test/models/token_authenticatable_test.rb +37 -0
  118. data/test/models/trackable_test.rb +5 -0
  119. data/test/models/validatable_test.rb +99 -0
  120. data/test/models_test.rb +77 -0
  121. data/test/oauth/config_test.rb +44 -0
  122. data/test/oauth/url_helpers_test.rb +47 -0
  123. data/test/orm/active_record.rb +9 -0
  124. data/test/orm/mongoid.rb +10 -0
  125. data/test/rails_app/app/active_record/admin.rb +6 -0
  126. data/test/rails_app/app/active_record/shim.rb +2 -0
  127. data/test/rails_app/app/active_record/user.rb +8 -0
  128. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  129. data/test/rails_app/app/controllers/admins_controller.rb +6 -0
  130. data/test/rails_app/app/controllers/application_controller.rb +9 -0
  131. data/test/rails_app/app/controllers/home_controller.rb +12 -0
  132. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  133. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  134. data/test/rails_app/app/controllers/users_controller.rb +18 -0
  135. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  136. data/test/rails_app/app/mongoid/admin.rb +9 -0
  137. data/test/rails_app/app/mongoid/shim.rb +24 -0
  138. data/test/rails_app/app/mongoid/user.rb +10 -0
  139. data/test/rails_app/config/application.rb +35 -0
  140. data/test/rails_app/config/boot.rb +13 -0
  141. data/test/rails_app/config/environment.rb +5 -0
  142. data/test/rails_app/config/environments/development.rb +19 -0
  143. data/test/rails_app/config/environments/production.rb +33 -0
  144. data/test/rails_app/config/environments/test.rb +33 -0
  145. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  146. data/test/rails_app/config/initializers/devise.rb +172 -0
  147. data/test/rails_app/config/initializers/inflections.rb +2 -0
  148. data/test/rails_app/config/initializers/secret_token.rb +2 -0
  149. data/test/rails_app/config/routes.rb +54 -0
  150. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +31 -0
  151. data/test/rails_app/db/schema.rb +52 -0
  152. data/test/rails_app/lib/shared_admin.rb +9 -0
  153. data/test/rails_app/lib/shared_user.rb +48 -0
  154. data/test/routes_test.rb +189 -0
  155. data/test/support/assertions.rb +24 -0
  156. data/test/support/helpers.rb +60 -0
  157. data/test/support/integration.rb +88 -0
  158. data/test/support/webrat/integrations/rails.rb +24 -0
  159. data/test/test_helper.rb +23 -0
  160. data/test/test_helpers_test.rb +101 -0
  161. metadata +335 -0
@@ -0,0 +1,56 @@
1
+ require 'test_helper'
2
+
3
+ class MyController < ApplicationController
4
+ include Devise::Controllers::InternalHelpers
5
+ end
6
+
7
+ class HelpersTest < ActionController::TestCase
8
+ tests MyController
9
+
10
+ def setup
11
+ @mock_warden = OpenStruct.new
12
+ @controller.request.env['warden'] = @mock_warden
13
+ @controller.request.env['devise.mapping'] = Devise.mappings[:user]
14
+ end
15
+
16
+ test 'get resource name from env' do
17
+ assert_equal :user, @controller.resource_name
18
+ end
19
+
20
+ test 'get resource class from env' do
21
+ assert_equal User, @controller.resource_class
22
+ end
23
+
24
+ test 'get resource instance variable from env' do
25
+ @controller.instance_variable_set(:@user, user = User.new)
26
+ assert_equal user, @controller.resource
27
+ end
28
+
29
+ test 'set resource instance variable from env' do
30
+ user = @controller.send(:resource_class).new
31
+ @controller.send(:resource=, user)
32
+
33
+ assert_equal user, @controller.send(:resource)
34
+ assert_equal user, @controller.instance_variable_get(:@user)
35
+ end
36
+
37
+ test 'resources methods are not controller actions' do
38
+ assert @controller.class.action_methods.empty?
39
+ end
40
+
41
+ test 'require no authentication tests current mapping' do
42
+ @mock_warden.expects(:authenticated?).with(:user).returns(true)
43
+ @mock_warden.expects(:user).with(:user).returns(User.new)
44
+ @controller.expects(:redirect_to).with(root_path)
45
+ @controller.send :require_no_authentication
46
+ end
47
+
48
+ test 'signed in resource returns signed in resource for current scope' do
49
+ @mock_warden.expects(:authenticate).with(:scope => :user).returns(User.new)
50
+ assert_kind_of User, @controller.signed_in_resource
51
+ end
52
+
53
+ test 'is a devise controller' do
54
+ assert @controller.devise_controller?
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+
3
+ class RoutesTest < ActionController::TestCase
4
+ tests ApplicationController
5
+
6
+ def assert_path_and_url(name, prepend_path=nil)
7
+ @request.path = '/users/session'
8
+ prepend_path = "#{prepend_path}_" if prepend_path
9
+
10
+ # Resource param
11
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", :user),
12
+ send(:"#{prepend_path}user_#{name}_path")
13
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", :user),
14
+ send(:"#{prepend_path}user_#{name}_url")
15
+
16
+ # Default url params
17
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", :user, :param => 123),
18
+ send(:"#{prepend_path}user_#{name}_path", :param => 123)
19
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", :user, :param => 123),
20
+ send(:"#{prepend_path}user_#{name}_url", :param => 123)
21
+
22
+ @request.path = nil
23
+ # With an object
24
+ assert_equal @controller.send(:"#{prepend_path}#{name}_path", User.new),
25
+ send(:"#{prepend_path}user_#{name}_path")
26
+ assert_equal @controller.send(:"#{prepend_path}#{name}_url", User.new),
27
+ send(:"#{prepend_path}user_#{name}_url")
28
+ end
29
+
30
+
31
+ test 'should alias session to mapped user session' do
32
+ assert_path_and_url :session
33
+ assert_path_and_url :session, :new
34
+ assert_path_and_url :session, :destroy
35
+ end
36
+
37
+ test 'should alias password to mapped user password' do
38
+ assert_path_and_url :password
39
+ assert_path_and_url :password, :new
40
+ assert_path_and_url :password, :edit
41
+ end
42
+
43
+ test 'should alias confirmation to mapped user confirmation' do
44
+ assert_path_and_url :confirmation
45
+ assert_path_and_url :confirmation, :new
46
+ end
47
+
48
+ test 'should alias unlock to mapped user unlock' do
49
+ assert_path_and_url :unlock
50
+ assert_path_and_url :unlock, :new
51
+ end
52
+
53
+ test 'should alias registration to mapped user registration' do
54
+ assert_path_and_url :registration
55
+ assert_path_and_url :registration, :new
56
+ assert_path_and_url :registration, :edit
57
+ assert_path_and_url :registration, :cancel
58
+ end
59
+ end
@@ -0,0 +1,65 @@
1
+ require 'test_helper'
2
+
3
+ module Devise
4
+ def self.yield_and_restore
5
+ @@warden_configured = nil
6
+ c, b = @@warden_config, @@warden_config_block
7
+ yield
8
+ ensure
9
+ @@warden_config, @@warden_config_block = c, b
10
+ end
11
+ end
12
+
13
+ class DeviseTest < ActiveSupport::TestCase
14
+ test 'model options can be configured through Devise' do
15
+ swap Devise, :confirm_within => 113, :pepper => "foo" do
16
+ assert_equal 113, Devise.confirm_within
17
+ assert_equal "foo", Devise.pepper
18
+ end
19
+ end
20
+
21
+ test 'setup block yields self' do
22
+ Devise.setup do |config|
23
+ assert_equal Devise, config
24
+ end
25
+ end
26
+
27
+ test 'stores warden configuration' do
28
+ assert_equal Devise::FailureApp, Devise.warden_config.failure_app
29
+ assert_equal :user, Devise.warden_config.default_scope
30
+ end
31
+
32
+ test 'warden manager user configuration through a block' do
33
+ Devise.yield_and_restore do
34
+ @executed = false
35
+ Devise.warden do |config|
36
+ @executed = true
37
+ assert_kind_of Warden::Config, config
38
+ end
39
+
40
+ Devise.configure_warden!
41
+ assert @executed
42
+ end
43
+ end
44
+
45
+ test 'add new module using the helper method' do
46
+ assert_nothing_raised(Exception) { Devise.add_module(:coconut) }
47
+ assert_equal 1, Devise::ALL.select { |v| v == :coconut }.size
48
+ assert_not Devise::STRATEGIES.include?(:coconut)
49
+ assert_not defined?(Devise::Models::Coconut)
50
+ Devise::ALL.delete(:coconut)
51
+
52
+ assert_nothing_raised(Exception) { Devise.add_module(:banana, :strategy => :fruits) }
53
+ assert_equal :fruits, Devise::STRATEGIES[:banana]
54
+ Devise::ALL.delete(:banana)
55
+ Devise::STRATEGIES.delete(:banana)
56
+
57
+ assert_nothing_raised(Exception) { Devise.add_module(:kivi, :controller => :fruits) }
58
+ assert_equal :fruits, Devise::CONTROLLERS[:kivi]
59
+ Devise::ALL.delete(:kivi)
60
+ Devise::CONTROLLERS.delete(:kivi)
61
+
62
+ assert_nothing_raised(Exception) { Devise.add_module(:authenticatable_again, :model => 'devise/model/authenticatable') }
63
+ assert defined?(Devise::Models::AuthenticatableAgain)
64
+ end
65
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ class Encryptors < ActiveSupport::TestCase
4
+ test 'should match a password created by authlogic' do
5
+ authlogic = "b623c3bc9c775b0eb8edb218a382453396fec4146422853e66ecc4b6bc32d7162ee42074dcb5f180a770dc38b5df15812f09bbf497a4a1b95fe5e7d2b8eb7eb4"
6
+ encryptor = Devise::Encryptors::AuthlogicSha512.digest('123mudar', 20, 'usZK_z_EAaF61Gwkw-ed', '')
7
+ assert_equal authlogic, encryptor
8
+ end
9
+
10
+ test 'should match a password created by restful_authentication' do
11
+ restful_authentication = "93110f71309ce91366375ea44e2a6f5cc73fa8d4"
12
+ encryptor = Devise::Encryptors::RestfulAuthenticationSha1.digest('123mudar', 10, '48901d2b247a54088acb7f8ea3e695e50fe6791b', 'fee9a51ec0a28d11be380ca6dee6b4b760c1a3bf')
13
+ assert_equal restful_authentication, encryptor
14
+ end
15
+
16
+ test 'should match a password created by clearance' do
17
+ clearance = "0f40bbae18ddefd7066276c3ef209d40729b0378"
18
+ encryptor = Devise::Encryptors::ClearanceSha1.digest('123mudar', nil, '65c58472c207c829f28c68619d3e3aefed18ab3f', nil)
19
+ assert_equal clearance, encryptor
20
+ end
21
+
22
+ Devise::ENCRYPTORS_LENGTH.each do |key, value|
23
+ test "should have length #{value} for #{key.inspect}" do
24
+ swap Devise, :encryptor => key do
25
+ encryptor = Devise::Encryptors.const_get(key.to_s.classify)
26
+ assert_equal value, encryptor.digest('a', 4, encryptor.salt(4), nil).size
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,148 @@
1
+ require 'test_helper'
2
+ require 'ostruct'
3
+
4
+ class FailureTest < ActiveSupport::TestCase
5
+ def self.context(name, &block)
6
+ instance_eval(&block)
7
+ end
8
+
9
+ def call_failure(env_params={})
10
+ env = {
11
+ 'REQUEST_URI' => 'http://test.host/',
12
+ 'HTTP_HOST' => 'test.host',
13
+ 'REQUEST_METHOD' => 'GET',
14
+ 'warden.options' => { :scope => :user },
15
+ 'rack.session' => {},
16
+ 'action_dispatch.request.formats' => Array(env_params.delete('formats') || :html),
17
+ 'rack.input' => "",
18
+ 'warden' => OpenStruct.new(:message => nil)
19
+ }.merge!(env_params)
20
+
21
+ @response = Devise::FailureApp.call(env).to_a
22
+ @request = ActionDispatch::Request.new(env)
23
+ end
24
+
25
+ context 'When redirecting' do
26
+ test 'return 302 status' do
27
+ call_failure
28
+ assert_equal 302, @response.first
29
+ end
30
+
31
+ test 'return to the default redirect location' do
32
+ call_failure
33
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
34
+ assert_equal 'http://test.host/users/sign_in', @response.second['Location']
35
+ end
36
+
37
+ test 'uses the proxy failure message as symbol' do
38
+ call_failure('warden' => OpenStruct.new(:message => :test))
39
+ assert_equal 'test', @request.flash[:alert]
40
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
41
+ end
42
+
43
+ test 'uses the proxy failure message as string' do
44
+ call_failure('warden' => OpenStruct.new(:message => 'Hello world'))
45
+ assert_equal 'Hello world', @request.flash[:alert]
46
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
47
+ end
48
+
49
+ test 'set content type to default text/html' do
50
+ call_failure
51
+ assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
52
+ end
53
+
54
+ test 'setup a default message' do
55
+ call_failure
56
+ assert_match /You are being/, @response.last.body
57
+ assert_match /redirected/, @response.last.body
58
+ assert_match /users\/sign_in/, @response.last.body
59
+ end
60
+
61
+ test 'works for any navigational format' do
62
+ swap Devise, :navigational_formats => [:xml] do
63
+ call_failure('formats' => :xml)
64
+ assert_equal 302, @response.first
65
+ end
66
+ end
67
+ end
68
+
69
+ context 'For HTTP request' do
70
+ test 'return 401 status' do
71
+ call_failure('formats' => :xml)
72
+ assert_equal 401, @response.first
73
+ end
74
+
75
+ test 'return WWW-authenticate headers if model allows' do
76
+ call_failure('formats' => :xml)
77
+ assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
78
+ end
79
+
80
+ test 'does not return WWW-authenticate headers if model does not allow' do
81
+ swap Devise, :http_authenticatable => false do
82
+ call_failure('formats' => :xml)
83
+ assert_nil @response.second["WWW-Authenticate"]
84
+ end
85
+ end
86
+
87
+ test 'works for any non navigational format' do
88
+ swap Devise, :navigational_formats => [] do
89
+ call_failure('formats' => :html)
90
+ assert_equal 401, @response.first
91
+ end
92
+ end
93
+
94
+ test 'uses the failure message as response body' do
95
+ call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
96
+ assert_match '<error>Invalid email or password.</error>', @response.third.body
97
+ end
98
+
99
+ context 'on ajax call' do
100
+ context 'when http_authenticatable_on_xhr is false' do
101
+ test 'dont return 401 with navigational formats' do
102
+ swap Devise, :http_authenticatable_on_xhr => false do
103
+ call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
104
+ assert_equal 302, @response.first
105
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
106
+ end
107
+ end
108
+
109
+ test 'dont return 401 with non navigational formats' do
110
+ swap Devise, :http_authenticatable_on_xhr => false do
111
+ call_failure('formats' => :json, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
112
+ assert_equal 302, @response.first
113
+ assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
114
+ end
115
+ end
116
+ end
117
+
118
+ context 'when http_authenticatable_on_xhr is true' do
119
+ test 'return 401' do
120
+ swap Devise, :http_authenticatable_on_xhr => true do
121
+ call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
122
+ assert_equal 401, @response.first
123
+ end
124
+ end
125
+
126
+ test 'skip WWW-Authenticate header' do
127
+ swap Devise, :http_authenticatable_on_xhr => true do
128
+ call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
129
+ assert_nil @response.second['WWW-Authenticate']
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ context 'With recall' do
137
+ test 'calls the original controller' do
138
+ env = {
139
+ "warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in" },
140
+ "devise.mapping" => Devise.mappings[:user],
141
+ "warden" => stub_everything
142
+ }
143
+ call_failure(env)
144
+ assert @response.third.body.include?('<h2>Sign in</h2>')
145
+ assert @response.third.body.include?('Invalid email or password.')
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,424 @@
1
+ require 'test_helper'
2
+
3
+ class AuthenticationSanityTest < ActionController::IntegrationTest
4
+ test 'home should be accessible without sign in' do
5
+ visit '/'
6
+ assert_response :success
7
+ assert_template 'home/index'
8
+ end
9
+
10
+ test 'sign in as user should not authenticate admin scope' do
11
+ sign_in_as_user
12
+ assert warden.authenticated?(:user)
13
+ assert_not warden.authenticated?(:admin)
14
+ end
15
+
16
+ test 'sign in as admin should not authenticate user scope' do
17
+ sign_in_as_admin
18
+ assert warden.authenticated?(:admin)
19
+ assert_not warden.authenticated?(:user)
20
+ end
21
+
22
+ test 'sign in as both user and admin at same time' do
23
+ sign_in_as_user
24
+ sign_in_as_admin
25
+ assert warden.authenticated?(:user)
26
+ assert warden.authenticated?(:admin)
27
+ end
28
+
29
+ test 'sign out as user should not touch admin authentication if sign_out_all_scopes is false' do
30
+ swap Devise, :sign_out_all_scopes => false do
31
+ sign_in_as_user
32
+ sign_in_as_admin
33
+ get destroy_user_session_path
34
+ assert_not warden.authenticated?(:user)
35
+ assert warden.authenticated?(:admin)
36
+ end
37
+ end
38
+
39
+ test 'sign out as admin should not touch user authentication if sign_out_all_scopes is false' do
40
+ swap Devise, :sign_out_all_scopes => false do
41
+ sign_in_as_user
42
+ sign_in_as_admin
43
+
44
+ get destroy_admin_session_path
45
+ assert_not warden.authenticated?(:admin)
46
+ assert warden.authenticated?(:user)
47
+ end
48
+ end
49
+
50
+ test 'sign out as user should also sign out admin if sign_out_all_scopes is true' do
51
+ swap Devise, :sign_out_all_scopes => true do
52
+ sign_in_as_user
53
+ sign_in_as_admin
54
+
55
+ get destroy_user_session_path
56
+ assert_not warden.authenticated?(:user)
57
+ assert_not warden.authenticated?(:admin)
58
+ end
59
+ end
60
+
61
+ test 'sign out as admin should also sign out user if sign_out_all_scopes is true' do
62
+ swap Devise, :sign_out_all_scopes => true do
63
+ sign_in_as_user
64
+ sign_in_as_admin
65
+
66
+ get destroy_admin_session_path
67
+ assert_not warden.authenticated?(:admin)
68
+ assert_not warden.authenticated?(:user)
69
+ end
70
+ end
71
+
72
+ test 'not signed in as admin should not be able to access admins actions' do
73
+ get admins_path
74
+ assert_redirected_to new_admin_session_path
75
+ assert_not warden.authenticated?(:admin)
76
+ end
77
+
78
+ test 'not signed in as admin should not be able to access private route restricted to admins' do
79
+ get private_path
80
+ assert_redirected_to new_admin_session_path
81
+ assert_not warden.authenticated?(:admin)
82
+ end
83
+
84
+ test 'signed in as user should not be able to access private route restricted to admins' do
85
+ sign_in_as_user
86
+ assert warden.authenticated?(:user)
87
+ assert_not warden.authenticated?(:admin)
88
+ get private_path
89
+ assert_redirected_to new_admin_session_path
90
+ end
91
+
92
+ test 'signed in as admin should be able to access private route restricted to admins' do
93
+ sign_in_as_admin
94
+ assert warden.authenticated?(:admin)
95
+ assert_not warden.authenticated?(:user)
96
+
97
+ get private_path
98
+
99
+ assert_response :success
100
+ assert_template 'home/private'
101
+ assert_contain 'Private!'
102
+ end
103
+
104
+ test 'signed in as user should not be able to access admins actions' do
105
+ sign_in_as_user
106
+ assert warden.authenticated?(:user)
107
+ assert_not warden.authenticated?(:admin)
108
+
109
+ get admins_path
110
+ assert_redirected_to new_admin_session_path
111
+ end
112
+
113
+ test 'signed in as admin should be able to access admin actions' do
114
+ sign_in_as_admin
115
+ assert warden.authenticated?(:admin)
116
+ assert_not warden.authenticated?(:user)
117
+
118
+ get admins_path
119
+
120
+ assert_response :success
121
+ assert_template 'admins/index'
122
+ assert_contain 'Welcome Admin'
123
+ end
124
+
125
+ test 'authenticated admin should not be able to sign as admin again' do
126
+ sign_in_as_admin
127
+ get new_admin_session_path
128
+
129
+ assert_response :redirect
130
+ assert_redirected_to admin_root_path
131
+ assert warden.authenticated?(:admin)
132
+ end
133
+
134
+ test 'authenticated admin should be able to sign out' do
135
+ sign_in_as_admin
136
+ assert warden.authenticated?(:admin)
137
+
138
+ get destroy_admin_session_path
139
+ assert_response :redirect
140
+ assert_redirected_to root_path
141
+
142
+ get root_path
143
+ assert_contain 'Signed out successfully'
144
+ assert_not warden.authenticated?(:admin)
145
+ end
146
+
147
+ test 'unauthenticated admin does not set message on sign out' do
148
+ get destroy_admin_session_path
149
+ assert_response :redirect
150
+ assert_redirected_to root_path
151
+
152
+ get root_path
153
+ assert_not_contain 'Signed out successfully'
154
+ end
155
+ end
156
+
157
+ class AuthenticationRedirectTest < ActionController::IntegrationTest
158
+ test 'redirect from warden shows sign in or sign up message' do
159
+ get admins_path
160
+
161
+ warden_path = new_admin_session_path
162
+ assert_redirected_to warden_path
163
+
164
+ get warden_path
165
+ assert_contain 'You need to sign in or sign up before continuing.'
166
+ end
167
+
168
+ test 'redirect to default url if no other was configured' do
169
+ sign_in_as_user
170
+ assert_template 'home/index'
171
+ assert_nil session[:"user_return_to"]
172
+ end
173
+
174
+ test 'redirect to requested url after sign in' do
175
+ get users_path
176
+ assert_redirected_to new_user_session_path
177
+ assert_equal users_path, session[:"user_return_to"]
178
+
179
+ follow_redirect!
180
+ sign_in_as_user :visit => false
181
+
182
+ assert_current_url '/users'
183
+ assert_nil session[:"user_return_to"]
184
+ end
185
+
186
+ test 'redirect to last requested url overwriting the stored return_to option' do
187
+ get expire_user_path(create_user)
188
+ assert_redirected_to new_user_session_path
189
+ assert_equal expire_user_path(create_user), session[:"user_return_to"]
190
+
191
+ get users_path
192
+ assert_redirected_to new_user_session_path
193
+ assert_equal users_path, session[:"user_return_to"]
194
+
195
+ follow_redirect!
196
+ sign_in_as_user :visit => false
197
+
198
+ assert_current_url '/users'
199
+ assert_nil session[:"user_return_to"]
200
+ end
201
+
202
+ test 'xml http requests does not store urls for redirect' do
203
+ get users_path, {}, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'
204
+ assert_equal 401, response.status
205
+ assert_nil session[:"user_return_to"]
206
+ end
207
+
208
+ test 'redirect to configured home path for a given scope after sign in' do
209
+ sign_in_as_admin
210
+ assert_equal "/admin_area/home", @request.path
211
+ end
212
+ end
213
+
214
+ class AuthenticationSessionTest < ActionController::IntegrationTest
215
+ test 'destroyed account is signed out' do
216
+ sign_in_as_user
217
+ get '/users'
218
+
219
+ User.destroy_all
220
+ get '/users'
221
+ assert_redirected_to new_user_session_path
222
+ end
223
+
224
+ test 'allows session to be set for a given scope' do
225
+ sign_in_as_user
226
+ get '/users'
227
+ assert_equal "Cart", @controller.user_session[:cart]
228
+ end
229
+
230
+ test 'does not explode when invalid user class is stored in session' do
231
+ klass = User
232
+ paths = ActiveSupport::Dependencies.autoload_paths.dup
233
+
234
+ begin
235
+ sign_in_as_user
236
+ assert warden.authenticated?(:user)
237
+
238
+ Object.send :remove_const, :User
239
+ ActiveSupport::Dependencies.autoload_paths.clear
240
+
241
+ visit "/users"
242
+ assert_not warden.authenticated?(:user)
243
+ ensure
244
+ Object.const_set(:User, klass)
245
+ ActiveSupport::Dependencies.autoload_paths.replace(paths)
246
+ end
247
+ end
248
+ end
249
+
250
+ class AuthenticationWithScopesTest < ActionController::IntegrationTest
251
+ test 'renders the scoped view if turned on and view is available' do
252
+ swap Devise, :scoped_views => true do
253
+ assert_raise Webrat::NotFoundError do
254
+ sign_in_as_user
255
+ end
256
+ assert_match /Special user view/, response.body
257
+ end
258
+ end
259
+
260
+ test 'renders the scoped view if turned on in an specific controller' do
261
+ begin
262
+ Devise::SessionsController.scoped_views = true
263
+ assert_raise Webrat::NotFoundError do
264
+ sign_in_as_user
265
+ end
266
+
267
+ assert_match /Special user view/, response.body
268
+ assert !Devise::PasswordsController.scoped_views?
269
+ ensure
270
+ Devise::SessionsController.send :remove_instance_variable, :@scoped_views
271
+ end
272
+ end
273
+
274
+ test 'does not render the scoped view if turned off' do
275
+ swap Devise, :scoped_views => false do
276
+ assert_nothing_raised do
277
+ sign_in_as_user
278
+ end
279
+ end
280
+ end
281
+
282
+ test 'does not render the scoped view if not available' do
283
+ swap Devise, :scoped_views => true do
284
+ assert_nothing_raised do
285
+ sign_in_as_admin
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ class AuthenticationOthersTest < ActionController::IntegrationTest
292
+ test 'uses the custom controller with the custom controller view' do
293
+ get '/admin_area/sign_in'
294
+ assert_contain 'Sign in'
295
+ assert_contain 'Welcome to "admins/sessions" controller!'
296
+ assert_contain 'Welcome to "sessions/new" view!'
297
+ end
298
+
299
+ test 'render 404 on roles without routes' do
300
+ get '/admin_area/password/new'
301
+ assert_equal 404, response.status
302
+ end
303
+
304
+ test 'render 404 on roles without mapping' do
305
+ assert_raise AbstractController::ActionNotFound do
306
+ get '/sign_in'
307
+ end
308
+ end
309
+
310
+ test 'sign in with script name' do
311
+ assert_nothing_raised do
312
+ get new_user_session_path, {}, "SCRIPT_NAME" => "/omg"
313
+ fill_in "email", :with => "user@test.com"
314
+ end
315
+ end
316
+
317
+ test 'registration in xml format works when recognizing path' do
318
+ assert_nothing_raised do
319
+ post user_registration_path(:format => 'xml', :user => {:email => "test@example.com", :password => "invalid"} )
320
+ end
321
+ end
322
+
323
+ test 'uses the mapping from router' do
324
+ sign_in_as_user :visit => "/as/sign_in"
325
+ assert warden.authenticated?(:user)
326
+ assert_not warden.authenticated?(:admin)
327
+ end
328
+
329
+ test 'uses the mapping from nested devise_for call' do
330
+ sign_in_as_user :visit => "/devise_for/sign_in"
331
+ assert warden.authenticated?(:user)
332
+ assert_not warden.authenticated?(:admin)
333
+ end
334
+ end
335
+
336
+ class AuthenticationRequestKeysTest < ActionController::IntegrationTest
337
+ test 'request keys are used on authentication' do
338
+ host! 'foo.bar.baz'
339
+
340
+ swap Devise, :request_keys => [:subdomain] do
341
+ User.expects(:find_for_authentication).with(:subdomain => 'foo', :email => 'user@test.com').returns(create_user)
342
+ sign_in_as_user
343
+ assert warden.authenticated?(:user)
344
+ end
345
+ end
346
+
347
+ test 'invalid request keys raises NoMethodError' do
348
+ swap Devise, :request_keys => [:unknown_method] do
349
+ assert_raise NoMethodError do
350
+ sign_in_as_user
351
+ end
352
+
353
+ assert_not warden.authenticated?(:user)
354
+ end
355
+ end
356
+
357
+ test 'blank request keys cause authentication to abort' do
358
+ host! 'test.com'
359
+
360
+ swap Devise, :request_keys => [:subdomain] do
361
+ sign_in_as_user
362
+ assert_contain "Invalid email or password."
363
+ assert_not warden.authenticated?(:user)
364
+ end
365
+ end
366
+
367
+ test 'blank request keys cause authentication to abort unless if marked as not required' do
368
+ host! 'test.com'
369
+
370
+ swap Devise, :request_keys => { :subdomain => false } do
371
+ sign_in_as_user
372
+ assert warden.authenticated?(:user)
373
+ end
374
+ end
375
+ end
376
+
377
+ class AuthenticationSignOutViaTest < ActionController::IntegrationTest
378
+ def sign_in!(scope)
379
+ sign_in_as_user(:visit => send("new_#{scope}_session_path"))
380
+ assert warden.authenticated?(scope)
381
+ end
382
+
383
+ test 'allow sign out via delete when sign_out_via provides only delete' do
384
+ sign_in!(:sign_out_via_delete)
385
+ delete destroy_sign_out_via_delete_session_path
386
+ assert_not warden.authenticated?(:sign_out_via_delete)
387
+ end
388
+
389
+ test 'do not allow sign out via get when sign_out_via provides only delete' do
390
+ sign_in!(:sign_out_via_delete)
391
+ get destroy_sign_out_via_delete_session_path
392
+ assert warden.authenticated?(:sign_out_via_delete)
393
+ end
394
+
395
+ test 'allow sign out via post when sign_out_via provides only post' do
396
+ sign_in!(:sign_out_via_post)
397
+ post destroy_sign_out_via_post_session_path
398
+ assert_not warden.authenticated?(:sign_out_via_post)
399
+ end
400
+
401
+ test 'do not allow sign out via get when sign_out_via provides only post' do
402
+ sign_in!(:sign_out_via_post)
403
+ get destroy_sign_out_via_delete_session_path
404
+ assert warden.authenticated?(:sign_out_via_post)
405
+ end
406
+
407
+ test 'allow sign out via delete when sign_out_via provides delete and post' do
408
+ sign_in!(:sign_out_via_delete_or_post)
409
+ delete destroy_sign_out_via_delete_or_post_session_path
410
+ assert_not warden.authenticated?(:sign_out_via_delete_or_post)
411
+ end
412
+
413
+ test 'allow sign out via post when sign_out_via provides delete and post' do
414
+ sign_in!(:sign_out_via_delete_or_post)
415
+ post destroy_sign_out_via_delete_or_post_session_path
416
+ assert_not warden.authenticated?(:sign_out_via_delete_or_post)
417
+ end
418
+
419
+ test 'do not allow sign out via get when sign_out_via provides delete and post' do
420
+ sign_in!(:sign_out_via_delete_or_post)
421
+ get destroy_sign_out_via_delete_or_post_session_path
422
+ assert warden.authenticated?(:sign_out_via_delete_or_post)
423
+ end
424
+ end