devise 1.5.1 → 2.0.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 (132) hide show
  1. data/CHANGELOG.rdoc +111 -68
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +7 -4
  4. data/app/controllers/devise/confirmations_controller.rb +3 -6
  5. data/app/controllers/devise/omniauth_callbacks_controller.rb +1 -3
  6. data/app/controllers/devise/passwords_controller.rb +3 -6
  7. data/app/controllers/devise/registrations_controller.rb +40 -42
  8. data/app/controllers/devise/sessions_controller.rb +2 -3
  9. data/app/controllers/devise/unlocks_controller.rb +4 -7
  10. data/app/controllers/devise_controller.rb +169 -0
  11. data/app/views/devise/_links.erb +25 -0
  12. data/app/views/devise/confirmations/new.html.erb +1 -1
  13. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  14. data/app/views/devise/passwords/edit.html.erb +1 -1
  15. data/app/views/devise/passwords/new.html.erb +1 -1
  16. data/app/views/devise/registrations/new.html.erb +1 -1
  17. data/app/views/devise/sessions/new.html.erb +1 -1
  18. data/app/views/devise/shared/_links.erb +3 -25
  19. data/app/views/devise/unlocks/new.html.erb +1 -1
  20. data/config/locales/en.yml +5 -6
  21. data/lib/devise/controllers/helpers.rb +8 -2
  22. data/lib/devise/controllers/scoped_views.rb +0 -16
  23. data/lib/devise/controllers/url_helpers.rb +16 -2
  24. data/lib/devise/delegator.rb +2 -2
  25. data/lib/devise/failure_app.rb +43 -8
  26. data/lib/devise/mapping.rb +1 -4
  27. data/lib/devise/models/authenticatable.rb +22 -1
  28. data/lib/devise/models/confirmable.rb +80 -22
  29. data/lib/devise/models/database_authenticatable.rb +5 -16
  30. data/lib/devise/models/lockable.rb +1 -1
  31. data/lib/devise/models/recoverable.rb +5 -5
  32. data/lib/devise/models/rememberable.rb +5 -20
  33. data/lib/devise/models/serializable.rb +5 -2
  34. data/lib/devise/models/timeoutable.rb +9 -7
  35. data/lib/devise/models/token_authenticatable.rb +1 -4
  36. data/lib/devise/models/validatable.rb +1 -1
  37. data/lib/devise/models.rb +1 -1
  38. data/lib/devise/modules.rb +2 -2
  39. data/lib/devise/omniauth/config.rb +1 -1
  40. data/lib/devise/orm/active_record.rb +6 -0
  41. data/lib/devise/param_filter.rb +1 -1
  42. data/lib/devise/path_checker.rb +7 -2
  43. data/lib/devise/rails/routes.rb +23 -14
  44. data/lib/devise/rails/warden_compat.rb +0 -83
  45. data/lib/devise/rails.rb +61 -0
  46. data/lib/devise/schema.rb +5 -0
  47. data/lib/devise/strategies/authenticatable.rb +14 -10
  48. data/lib/devise/strategies/token_authenticatable.rb +3 -3
  49. data/lib/devise/version.rb +1 -1
  50. data/lib/devise.rb +56 -33
  51. data/lib/generators/active_record/devise_generator.rb +40 -2
  52. data/lib/generators/active_record/templates/migration.rb +1 -19
  53. data/lib/generators/active_record/templates/migration_existing.rb +1 -9
  54. data/lib/generators/devise/views_generator.rb +6 -14
  55. data/lib/generators/mongoid/devise_generator.rb +43 -0
  56. data/lib/generators/templates/devise.rb +28 -14
  57. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +1 -1
  58. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  59. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +1 -1
  60. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  61. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +1 -1
  62. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +1 -1
  63. data/test/controllers/internal_helpers_test.rb +5 -4
  64. data/test/delegator_test.rb +19 -0
  65. data/test/devise_test.rb +2 -2
  66. data/test/failure_app_test.rb +24 -20
  67. data/test/generators/active_record_generator_test.rb +3 -13
  68. data/test/generators/views_generator_test.rb +1 -1
  69. data/test/integration/authenticatable_test.rb +4 -7
  70. data/test/integration/confirmable_test.rb +55 -3
  71. data/test/integration/http_authenticatable_test.rb +20 -5
  72. data/test/integration/lockable_test.rb +26 -14
  73. data/test/integration/registerable_test.rb +33 -2
  74. data/test/integration/rememberable_test.rb +0 -50
  75. data/test/integration/timeoutable_test.rb +18 -4
  76. data/test/integration/token_authenticatable_test.rb +5 -5
  77. data/test/integration/trackable_test.rb +6 -6
  78. data/test/mapping_test.rb +2 -3
  79. data/test/models/confirmable_test.rb +101 -8
  80. data/test/models/database_authenticatable_test.rb +19 -0
  81. data/test/models/encryptable_test.rb +1 -1
  82. data/test/models/lockable_test.rb +13 -0
  83. data/test/models/recoverable_test.rb +0 -27
  84. data/test/models/rememberable_test.rb +41 -160
  85. data/test/models/serializable_test.rb +1 -1
  86. data/test/models/timeoutable_test.rb +14 -0
  87. data/test/models_test.rb +7 -7
  88. data/test/path_checker_test.rb +21 -0
  89. data/test/rails_app/app/mongoid/admin.rb +22 -1
  90. data/test/rails_app/app/mongoid/user.rb +35 -0
  91. data/test/rails_app/config/initializers/devise.rb +6 -7
  92. data/test/rails_app/config/routes.rb +3 -5
  93. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +58 -12
  94. data/test/rails_app/lib/shared_admin.rb +6 -2
  95. data/test/rails_app/log/development.log +13 -0
  96. data/test/rails_app/log/test.log +319550 -0
  97. data/test/routes_test.rb +4 -0
  98. data/test/support/assertions.rb +4 -1
  99. data/test/support/helpers.rb +0 -17
  100. data/test/support/integration.rb +3 -1
  101. data/test/test_helpers_test.rb +2 -2
  102. data/test/tmp/app/views/devise/_links.erb +25 -0
  103. data/test/tmp/app/views/devise/confirmations/new.html.erb +15 -0
  104. data/test/tmp/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  105. data/test/tmp/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  106. data/test/tmp/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  107. data/test/tmp/app/views/devise/passwords/edit.html.erb +19 -0
  108. data/test/tmp/app/views/devise/passwords/new.html.erb +15 -0
  109. data/test/tmp/app/views/devise/registrations/edit.html.erb +22 -0
  110. data/test/tmp/app/views/devise/registrations/new.html.erb +17 -0
  111. data/test/tmp/app/views/devise/sessions/new.html.erb +15 -0
  112. data/test/tmp/app/views/devise/unlocks/new.html.erb +15 -0
  113. data/test/tmp/app/views/users/_links.erb +25 -0
  114. data/test/tmp/app/views/users/confirmations/new.html.erb +15 -0
  115. data/test/tmp/app/views/users/mailer/confirmation_instructions.html.erb +5 -0
  116. data/test/tmp/app/views/users/mailer/reset_password_instructions.html.erb +8 -0
  117. data/test/tmp/app/views/users/mailer/unlock_instructions.html.erb +7 -0
  118. data/test/tmp/app/views/users/passwords/edit.html.erb +19 -0
  119. data/test/tmp/app/views/users/passwords/new.html.erb +15 -0
  120. data/test/tmp/app/views/users/registrations/edit.html.erb +22 -0
  121. data/test/tmp/app/views/users/registrations/new.html.erb +17 -0
  122. data/test/tmp/app/views/users/sessions/new.html.erb +15 -0
  123. data/test/tmp/app/views/users/unlocks/new.html.erb +15 -0
  124. metadata +83 -27
  125. data/.gitignore +0 -12
  126. data/.travis.yml +0 -13
  127. data/Gemfile +0 -35
  128. data/Rakefile +0 -34
  129. data/devise.gemspec +0 -25
  130. data/lib/devise/controllers/internal_helpers.rb +0 -154
  131. data/lib/devise/controllers/shared_helpers.rb +0 -26
  132. data/test/schema_test.rb +0 -33
@@ -1,5 +1,5 @@
1
- # Use this hook to configure devise mailer, warden hooks and so forth. The first
2
- # four configuration values can also be set straight in your models.
1
+ # Use this hook to configure devise mailer, warden hooks and so forth.
2
+ # Many of these configuration options can be set straight in your model.
3
3
  Devise.setup do |config|
4
4
  # ==> Mailer Configuration
5
5
  # Configure the e-mail address which will be shown in Devise::Mailer,
@@ -9,6 +9,9 @@ Devise.setup do |config|
9
9
  # Configure the class responsible to send e-mails.
10
10
  # config.mailer = "Devise::Mailer"
11
11
 
12
+ # Automatically apply schema changes in tableless databases
13
+ config.apply_schema = false
14
+
12
15
  # ==> ORM configuration
13
16
  # Load and configure the ORM. Supports :active_record (default) and
14
17
  # :mongoid (bson_ext recommended) by default. Other ORMs may be
@@ -43,9 +46,15 @@ Devise.setup do |config|
43
46
  config.strip_whitespace_keys = [ :email ]
44
47
 
45
48
  # Tell if authentication through request.params is enabled. True by default.
49
+ # It can be set to an array that will enable params authentication only for the
50
+ # given strategies, for example, `config.params_authenticatable = [:database]` will
51
+ # enable it only for database (email + password) authentication.
46
52
  # config.params_authenticatable = true
47
53
 
48
54
  # Tell if authentication through HTTP Basic Auth is enabled. False by default.
55
+ # It can be set to an array that will enable http authentication only for the
56
+ # given strategies, for example, `config.http_authenticatable = [:token]` will
57
+ # enable it only for token authentication.
49
58
  # config.http_authenticatable = false
50
59
 
51
60
  # If http headers should be returned for AJAX requests. True by default.
@@ -59,6 +68,13 @@ Devise.setup do |config|
59
68
  # Does not affect registerable.
60
69
  # config.paranoid = true
61
70
 
71
+ # By default Devise will store the user in session. You can skip storage for
72
+ # :http_auth and :token_auth by adding those symbols to the array below.
73
+ # Notice that if you are skipping storage for all authentication paths, you
74
+ # may want to disable generating routes to Devise's sessions controller by
75
+ # passing :skip => :sessions to `devise_for` in your config/routes.rb
76
+ config.skip_session_storage = [:http_auth]
77
+
62
78
  # ==> Configuration for :database_authenticatable
63
79
  # For bcrypt, this is the cost for hashing the password and defaults to 10. If
64
80
  # using other encryptors, it sets how many times you want the password re-encrypted.
@@ -77,7 +93,13 @@ Devise.setup do |config|
77
93
  # able to access the website for two days without confirming his account,
78
94
  # access will be blocked just in the third day. Default is 0.days, meaning
79
95
  # the user cannot access the website without confirming his account.
80
- # config.confirm_within = 2.days
96
+ # config.allow_unconfirmed_access_for = 2.days
97
+
98
+ # If true, requires any email changes to be confirmed (exctly the same way as
99
+ # initial account confirmation) to be applied. Requires additional unconfirmed_email
100
+ # db field (see migrations). Until confirmed new email is stored in
101
+ # unconfirmed email column, and copied to email column on successful confirmation.
102
+ config.reconfirmable = true
81
103
 
82
104
  # Defines which key will be used when confirming an account
83
105
  # config.confirmation_keys = [ :email ]
@@ -86,9 +108,6 @@ Devise.setup do |config|
86
108
  # The time the user will be remembered without asking for credentials again.
87
109
  # config.remember_for = 2.weeks
88
110
 
89
- # If true, a valid remember token can be re-used between multiple browsers.
90
- # config.remember_across_browsers = true
91
-
92
111
  # If true, extends the user's remember period when remembered via cookie.
93
112
  # config.extend_remember_period = false
94
113
 
@@ -145,7 +164,7 @@ Devise.setup do |config|
145
164
  # Time interval you can reset your password with a reset password key.
146
165
  # Don't put a too small interval or your users won't have the time to
147
166
  # change their passwords.
148
- config.reset_password_within = 2.hours
167
+ config.reset_password_within = 6.hours
149
168
 
150
169
  # ==> Configuration for :encryptable
151
170
  # Allow you to use another encryption algorithm besides bcrypt (default). You can use
@@ -159,10 +178,6 @@ Devise.setup do |config|
159
178
  # Defines name of the authentication token params key
160
179
  # config.token_authentication_key = :auth_token
161
180
 
162
- # If true, authentication through token does not store user in session and needs
163
- # to be supplied on each request. Useful if you are using the token as API token.
164
- # config.stateless_token = false
165
-
166
181
  # ==> Scopes configuration
167
182
  # Turn scoped views on. Before rendering "sessions/new", it will first check for
168
183
  # "users/sessions/new". It's turned off by default because it's slower if you
@@ -186,9 +201,8 @@ Devise.setup do |config|
186
201
  # If you have any extra navigational formats, like :iphone or :mobile, you
187
202
  # should add them to the navigational formats lists.
188
203
  #
189
- # The :"*/*" and "*/*" formats below is required to match Internet
190
- # Explorer requests.
191
- # config.navigational_formats = [:"*/*", "*/*", :html]
204
+ # The "*/*" below is required to match Internet Explorer requests.
205
+ # config.navigational_formats = ["*/*", :html]
192
206
 
193
207
  # The default HTTP method used to sign out a resource. Default is :delete.
194
208
  config.sign_out_via = :delete
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -16,4 +16,4 @@
16
16
  </div>
17
17
  <% end %>
18
18
 
19
- <%= render :partial => "devise/shared/links" %>
19
+ <%= render "links" %>
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -14,4 +14,4 @@
14
14
  </div>
15
15
  <% end %>
16
16
 
17
- <%= render :partial => "devise/shared/links" %>
17
+ <%= render "links" %>
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -12,4 +12,4 @@
12
12
  </div>
13
13
  <% end %>
14
14
 
15
- <%= render :partial => "devise/shared/links" %>
15
+ <%= render "links" %>
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class MyController < ApplicationController
4
- include Devise::Controllers::InternalHelpers
3
+ class MyController < DeviseController
5
4
  end
6
5
 
7
6
  class HelpersTest < ActionController::TestCase
@@ -45,10 +44,12 @@ class HelpersTest < ActionController::TestCase
45
44
  @controller.send :require_no_authentication
46
45
  end
47
46
 
48
- test 'require no authentication skips if no inputs are available' do
47
+ test 'require no authentication only checks if already authenticated if no inputs strategies are available' do
49
48
  Devise.mappings[:user].expects(:no_input_strategies).returns([])
50
49
  @mock_warden.expects(:authenticate?).never
51
- @controller.expects(:redirect_to).never
50
+ @mock_warden.expects(:authenticated?).with(:user).once.returns(true)
51
+ @mock_warden.expects(:user).with(:user).returns(User.new)
52
+ @controller.expects(:redirect_to).with(root_path)
52
53
  @controller.send :require_no_authentication
53
54
  end
54
55
 
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class DelegatorTest < ActiveSupport::TestCase
4
+ def delegator
5
+ Devise::Delegator.new
6
+ end
7
+
8
+ test 'failure_app returns default failure app if no warden options in env' do
9
+ assert_equal Devise::FailureApp, delegator.failure_app({})
10
+ end
11
+
12
+ test 'failure_app returns default failure app if no scope in warden options' do
13
+ assert_equal Devise::FailureApp, delegator.failure_app({"warden.options" => {}})
14
+ end
15
+
16
+ test 'failure_app returns associated failure app by scope in the given environment' do
17
+ assert_kind_of Proc, delegator.failure_app({"warden.options" => {:scope => "manager"}})
18
+ end
19
+ end
data/test/devise_test.rb CHANGED
@@ -12,8 +12,8 @@ end
12
12
 
13
13
  class DeviseTest < ActiveSupport::TestCase
14
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
15
+ swap Devise, :allow_unconfirmed_access_for => 113, :pepper => "foo" do
16
+ assert_equal 113, Devise.allow_unconfirmed_access_for
17
17
  assert_equal "foo", Devise.pepper
18
18
  end
19
19
  end
@@ -3,7 +3,9 @@ require 'ostruct'
3
3
 
4
4
  class FailureTest < ActiveSupport::TestCase
5
5
  class RootFailureApp < Devise::FailureApp
6
- undef_method :new_user_session_path
6
+ def fake_app
7
+ Object.new
8
+ end
7
9
  end
8
10
 
9
11
  def self.context(name, &block)
@@ -41,15 +43,17 @@ class FailureTest < ActiveSupport::TestCase
41
43
  end
42
44
 
43
45
  test 'return to the root path if no session path is available' do
44
- call_failure :app => RootFailureApp
45
- assert_equal 302, @response.first
46
- assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
47
- assert_equal 'http://test.host/', @response.second['Location']
46
+ swap Devise, :router_name => :fake_app do
47
+ call_failure :app => RootFailureApp
48
+ assert_equal 302, @response.first
49
+ assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
50
+ assert_equal 'http://test.host/', @response.second['Location']
51
+ end
48
52
  end
49
53
 
50
54
  test 'uses the proxy failure message as symbol' do
51
- call_failure('warden' => OpenStruct.new(:message => :test))
52
- assert_equal 'test', @request.flash[:alert]
55
+ call_failure('warden' => OpenStruct.new(:message => :invalid))
56
+ assert_equal 'Invalid email or password.', @request.flash[:alert]
53
57
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
54
58
  end
55
59
 
@@ -73,14 +77,14 @@ class FailureTest < ActiveSupport::TestCase
73
77
 
74
78
  test 'works for any navigational format' do
75
79
  swap Devise, :navigational_formats => [:xml] do
76
- call_failure('formats' => :xml)
80
+ call_failure('formats' => Mime::XML)
77
81
  assert_equal 302, @response.first
78
82
  end
79
83
  end
80
84
 
81
85
  test 'redirects the correct format if it is a non-html format request' do
82
86
  swap Devise, :navigational_formats => [:js] do
83
- call_failure('formats' => :js)
87
+ call_failure('formats' => Mime::JS)
84
88
  assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
85
89
  end
86
90
  end
@@ -88,18 +92,18 @@ class FailureTest < ActiveSupport::TestCase
88
92
 
89
93
  context 'For HTTP request' do
90
94
  test 'return 401 status' do
91
- call_failure('formats' => :xml)
95
+ call_failure('formats' => Mime::XML)
92
96
  assert_equal 401, @response.first
93
97
  end
94
98
 
95
99
  test 'return appropriate body for xml' do
96
- call_failure('formats' => :xml)
100
+ call_failure('formats' => Mime::XML)
97
101
  result = %(<?xml version="1.0" encoding="UTF-8"?>\n<errors>\n <error>You need to sign in or sign up before continuing.</error>\n</errors>\n)
98
102
  assert_equal result, @response.last.body
99
103
  end
100
104
 
101
105
  test 'return appropriate body for json' do
102
- call_failure('formats' => :json)
106
+ call_failure('formats' => Mime::JSON)
103
107
  result = %({"error":"You need to sign in or sign up before continuing."})
104
108
  assert_equal result, @response.last.body
105
109
  end
@@ -110,26 +114,26 @@ class FailureTest < ActiveSupport::TestCase
110
114
  end
111
115
 
112
116
  test 'return WWW-authenticate headers if model allows' do
113
- call_failure('formats' => :xml)
117
+ call_failure('formats' => Mime::XML)
114
118
  assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
115
119
  end
116
120
 
117
121
  test 'does not return WWW-authenticate headers if model does not allow' do
118
122
  swap Devise, :http_authenticatable => false do
119
- call_failure('formats' => :xml)
123
+ call_failure('formats' => Mime::XML)
120
124
  assert_nil @response.second["WWW-Authenticate"]
121
125
  end
122
126
  end
123
127
 
124
128
  test 'works for any non navigational format' do
125
129
  swap Devise, :navigational_formats => [] do
126
- call_failure('formats' => :html)
130
+ call_failure('formats' => Mime::HTML)
127
131
  assert_equal 401, @response.first
128
132
  end
129
133
  end
130
134
 
131
135
  test 'uses the failure message as response body' do
132
- call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
136
+ call_failure('formats' => Mime::XML, 'warden' => OpenStruct.new(:message => :invalid))
133
137
  assert_match '<error>Invalid email or password.</error>', @response.third.body
134
138
  end
135
139
 
@@ -137,7 +141,7 @@ class FailureTest < ActiveSupport::TestCase
137
141
  context 'when http_authenticatable_on_xhr is false' do
138
142
  test 'dont return 401 with navigational formats' do
139
143
  swap Devise, :http_authenticatable_on_xhr => false do
140
- call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
144
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
141
145
  assert_equal 302, @response.first
142
146
  assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
143
147
  end
@@ -145,7 +149,7 @@ class FailureTest < ActiveSupport::TestCase
145
149
 
146
150
  test 'dont return 401 with non navigational formats' do
147
151
  swap Devise, :http_authenticatable_on_xhr => false do
148
- call_failure('formats' => :json, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
152
+ call_failure('formats' => Mime::JSON, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
149
153
  assert_equal 302, @response.first
150
154
  assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
151
155
  end
@@ -155,14 +159,14 @@ class FailureTest < ActiveSupport::TestCase
155
159
  context 'when http_authenticatable_on_xhr is true' do
156
160
  test 'return 401' do
157
161
  swap Devise, :http_authenticatable_on_xhr => true do
158
- call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
162
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
159
163
  assert_equal 401, @response.first
160
164
  end
161
165
  end
162
166
 
163
167
  test 'skip WWW-Authenticate header' do
164
168
  swap Devise, :http_authenticatable_on_xhr => true do
165
- call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
169
+ call_failure('formats' => Mime::HTML, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
166
170
  assert_nil @response.second['WWW-Authenticate']
167
171
  end
168
172
  end
@@ -8,20 +8,10 @@ if DEVISE_ORM == :active_record
8
8
  destination File.expand_path("../../tmp", __FILE__)
9
9
  setup :prepare_destination
10
10
 
11
- test "all files are properly created" do
12
- with_rails_version :MAJOR => 3, :MINOR => 0 do
13
- run_generator %w(monster)
14
- assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
15
- assert_migration "db/migrate/devise_create_monsters.rb", /def self\.up/
16
- end
17
- end
18
-
19
11
  test "all files are properly created with rails31 migration syntax" do
20
- with_rails_version :MAJOR => 3, :MINOR => 1 do
21
- run_generator %w(monster)
22
- assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
23
- assert_migration "db/migrate/devise_create_monsters.rb", /def change/
24
- end
12
+ run_generator %w(monster)
13
+ assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
14
+ assert_migration "db/migrate/devise_create_monsters.rb", /def change/
25
15
  end
26
16
 
27
17
  test "update model migration when model exists" do
@@ -46,7 +46,7 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
46
46
  assert_file "app/views/#{scope}/registrations/new.html.erb"
47
47
  assert_file "app/views/#{scope}/registrations/edit.html.erb"
48
48
  assert_file "app/views/#{scope}/sessions/new.html.erb"
49
- assert_file "app/views/#{scope}/shared/_links.erb"
50
49
  assert_file "app/views/#{scope}/unlocks/new.html.erb"
50
+ assert_file "app/views/#{scope}/_links.erb"
51
51
  end
52
52
  end
@@ -407,7 +407,10 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
407
407
 
408
408
  test 'sign in stub in xml format' do
409
409
  get new_user_session_path(:format => 'xml')
410
- assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>\n <email></email>\n <password nil=\"true\"></password>\n</user>\n", response.body
410
+ assert_match '<?xml version="1.0" encoding="UTF-8"?>', response.body
411
+ assert_match /<user>.*<\/user>/m, response.body
412
+ assert_match '<email></email>', response.body
413
+ assert_match '<password nil="true"></password>', response.body
411
414
  end
412
415
 
413
416
  test 'sign in stub in json format' do
@@ -432,12 +435,6 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
432
435
  assert_not warden.authenticated?(:admin)
433
436
  end
434
437
 
435
- test 'uses the mapping from nested devise_for call' do
436
- sign_in_as_user :visit => "/devise_for/sign_in"
437
- assert warden.authenticated?(:user)
438
- assert_not warden.authenticated?(:admin)
439
- end
440
-
441
438
  test 'sign in with xml format returns xml response' do
442
439
  create_user
443
440
  post user_session_path(:format => 'xml'), :user => {:email => "user@test.com", :password => '123456'}
@@ -98,7 +98,7 @@ class ConfirmationTest < ActionController::IntegrationTest
98
98
  end
99
99
 
100
100
  test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
101
- swap Devise, :confirm_within => 0.days do
101
+ swap Devise, :allow_unconfirmed_access_for => 0.days do
102
102
  sign_in_as_user(:confirm => false)
103
103
 
104
104
  assert_contain 'You have to confirm your account before continuing'
@@ -107,7 +107,7 @@ class ConfirmationTest < ActionController::IntegrationTest
107
107
  end
108
108
 
109
109
  test 'not confirmed user should not see confirmation message if invalid credentials are given' do
110
- swap Devise, :confirm_within => 0.days do
110
+ swap Devise, :allow_unconfirmed_access_for => 0.days do
111
111
  sign_in_as_user(:confirm => false) do
112
112
  fill_in 'password', :with => 'invalid'
113
113
  end
@@ -118,7 +118,7 @@ class ConfirmationTest < ActionController::IntegrationTest
118
118
  end
119
119
 
120
120
  test 'not confirmed user but configured with some days to confirm should be able to sign in' do
121
- swap Devise, :confirm_within => 1.day do
121
+ swap Devise, :allow_unconfirmed_access_for => 1.day do
122
122
  sign_in_as_user(:confirm => false)
123
123
 
124
124
  assert_response :success
@@ -201,3 +201,55 @@ class ConfirmationTest < ActionController::IntegrationTest
201
201
  end
202
202
  end
203
203
  end
204
+
205
+ class ConfirmationOnChangeTest < ActionController::IntegrationTest
206
+ def create_second_admin(options={})
207
+ @admin = nil
208
+ create_admin(options)
209
+ end
210
+
211
+ def visit_admin_confirmation_with_token(confirmation_token)
212
+ visit admin_confirmation_path(:confirmation_token => confirmation_token)
213
+ end
214
+
215
+ test 'admin should be able to request a new confirmation after email changed' do
216
+ admin = create_admin
217
+ admin.update_attributes(:email => 'new_test@example.com')
218
+
219
+ visit new_admin_session_path
220
+ click_link "Didn't receive confirmation instructions?"
221
+
222
+ fill_in 'email', :with => admin.unconfirmed_email
223
+ assert_difference "ActionMailer::Base.deliveries.size" do
224
+ click_button 'Resend confirmation instructions'
225
+ end
226
+
227
+ assert_current_url '/admin_area/sign_in'
228
+ assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
229
+ end
230
+
231
+ test 'admin with valid confirmation token should be able to confirm email after email changed' do
232
+ admin = create_admin
233
+ admin.update_attributes(:email => 'new_test@example.com')
234
+ assert_equal 'new_test@example.com', admin.unconfirmed_email
235
+ visit_admin_confirmation_with_token(admin.confirmation_token)
236
+
237
+ assert_contain 'Your account was successfully confirmed.'
238
+ assert_current_url '/admin_area/home'
239
+ assert admin.reload.confirmed?
240
+ assert_not admin.reload.pending_reconfirmation?
241
+ end
242
+
243
+ test 'admin email should be unique also within unconfirmed_email' do
244
+ admin = create_admin
245
+ admin.update_attributes(:email => 'new_admin_test@example.com')
246
+ assert_equal 'new_admin_test@example.com', admin.unconfirmed_email
247
+
248
+ create_second_admin(:email => "new_admin_test@example.com")
249
+
250
+ visit_admin_confirmation_with_token(admin.confirmation_token)
251
+ assert_have_selector '#error_explanation'
252
+ assert_contain /Email.*already.*taken/
253
+ assert admin.reload.pending_reconfirmation?
254
+ end
255
+ end
@@ -4,7 +4,7 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
4
4
  test 'handles unverified requests gets rid of caches but continues signed in' do
5
5
  swap UsersController, :allow_forgery_protection => true do
6
6
  create_user
7
- post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{ActiveSupport::Base64.encode64("user@test.com:123456")}"
7
+ post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("user@test.com:123456")}"
8
8
  assert warden.authenticated?(:user)
9
9
  assert_equal "User is authenticated", response.body
10
10
  end
@@ -12,9 +12,24 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
12
12
 
13
13
  test 'sign in should authenticate with http' do
14
14
  sign_in_as_new_user_with_http
15
- assert_response :success
15
+ assert_response 200
16
16
  assert_match '<email>user@test.com</email>', response.body
17
17
  assert warden.authenticated?(:user)
18
+
19
+ get users_path(:format => :xml)
20
+ assert_response 200
21
+ end
22
+
23
+ test 'sign in should authenticate with http but not emit a cookie if skipping session storage' do
24
+ swap Devise, :skip_session_storage => [:http_auth] do
25
+ sign_in_as_new_user_with_http
26
+ assert_response 200
27
+ assert_match '<email>user@test.com</email>', response.body
28
+ assert warden.authenticated?(:user)
29
+
30
+ get users_path(:format => :xml)
31
+ assert_response 401
32
+ end
18
33
  end
19
34
 
20
35
  test 'returns a custom response with www-authenticate header on failures' do
@@ -59,7 +74,7 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
59
74
  token = "token_containing_so_many_characters_that_the_base64_encoding_will_wrap"
60
75
  user = create_user
61
76
  user.update_attribute :authentication_token, token
62
- get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{ActiveSupport::Base64.encode64("#{token}:x")}"
77
+ get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("#{token}:x")}"
63
78
  assert_response :success
64
79
  assert_match "<email>user@test.com</email>", response.body
65
80
  assert warden.authenticated?(:user)
@@ -69,14 +84,14 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
69
84
 
70
85
  def sign_in_as_new_user_with_http(username="user@test.com", password="123456")
71
86
  user = create_user
72
- get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{ActiveSupport::Base64.encode64("#{username}:#{password}")}"
87
+ get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("#{username}:#{password}")}"
73
88
  user
74
89
  end
75
90
 
76
91
  # Sign in with oauth2 token. This is just to test that it isn't misinterpreted as basic authentication
77
92
  def add_oauth2_header
78
93
  user = create_user
79
- get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "OAuth #{ActiveSupport::Base64.encode64("#{user.email}:123456")}"
94
+ get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "OAuth #{Base64.encode64("#{user.email}:123456")}"
80
95
  end
81
96
 
82
97
  end
@@ -80,22 +80,15 @@ class LockTest < ActionController::IntegrationTest
80
80
 
81
81
  visit_user_unlock_with_token(user.unlock_token)
82
82
 
83
- assert_current_url '/'
84
- assert_contain 'Your account was successfully unlocked.'
83
+ assert_current_url "/users/sign_in"
84
+ assert_contain 'Your account has been unlocked successfully. Please sign in to continue.'
85
85
 
86
86
  assert_not user.reload.access_locked?
87
87
  end
88
88
 
89
- test "sign in user automatically after unlocking its account" do
89
+ test "redirect user to sign in page after unlocking its account" do
90
90
  user = create_user(:locked => true)
91
91
  visit_user_unlock_with_token(user.unlock_token)
92
- assert warden.authenticated?(:user)
93
- end
94
-
95
- test "user should not be able to sign in when locked" do
96
- user = sign_in_as_user(:locked => true)
97
- assert_template 'sessions/new'
98
- assert_contain 'Your account is locked.'
99
92
  assert_not warden.authenticated?(:user)
100
93
  end
101
94
 
@@ -113,10 +106,29 @@ class LockTest < ActionController::IntegrationTest
113
106
 
114
107
  test 'error message is configurable by resource name' do
115
108
  store_translations :en, :devise => {
116
- :failure => { :user => { :locked => "You are locked!" } }
109
+ :failure => {:user => {:locked => "You are locked!"}}
117
110
  } do
118
- user = sign_in_as_user(:locked => true)
119
- assert_contain 'You are locked!'
111
+
112
+ user = create_user(:locked => true)
113
+ user.failed_attempts = User.maximum_attempts + 1
114
+ user.save!
115
+
116
+ sign_in_as_user(:password => "invalid")
117
+ assert_contain "You are locked!"
118
+ end
119
+ end
120
+
121
+ test "user should not be able to sign in when locked" do
122
+ store_translations :en, :devise => {
123
+ :failure => {:user => {:locked => "You are locked!"}}
124
+ } do
125
+
126
+ user = create_user(:locked => true)
127
+ user.failed_attempts = User.maximum_attempts + 1
128
+ user.save!
129
+
130
+ sign_in_as_user(:password => "123456")
131
+ assert_contain "You are locked!"
120
132
  end
121
133
  end
122
134
 
@@ -157,7 +169,7 @@ class LockTest < ActionController::IntegrationTest
157
169
 
158
170
  test "when using json to ask a unlock request, should not return the user" do
159
171
  user = create_user(:locked => true)
160
- post user_unlock_path(:format => "json", :user => {:email => user.email})
172
+ post user_unlock_path(:format => "json", :user => {:email => user.email})
161
173
  assert_response :success
162
174
  assert_equal response.body, {}.to_json
163
175
  end