devise 1.1.rc2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (77) hide show
  1. data/CHANGELOG.rdoc +22 -2
  2. data/Gemfile +7 -13
  3. data/Gemfile.lock +118 -0
  4. data/README.rdoc +15 -13
  5. data/app/controllers/devise/unlocks_controller.rb +0 -7
  6. data/app/mailers/devise/mailer.rb +7 -4
  7. data/app/views/devise/confirmations/new.html.erb +1 -1
  8. data/app/views/devise/passwords/new.html.erb +1 -1
  9. data/app/views/devise/unlocks/new.html.erb +1 -1
  10. data/lib/devise.rb +27 -9
  11. data/lib/devise/controllers/helpers.rb +19 -5
  12. data/lib/devise/controllers/internal_helpers.rb +2 -8
  13. data/lib/devise/encryptors/base.rb +1 -1
  14. data/lib/devise/encryptors/bcrypt.rb +2 -2
  15. data/lib/devise/failure_app.rb +6 -2
  16. data/lib/devise/hooks/rememberable.rb +9 -1
  17. data/lib/devise/mapping.rb +15 -50
  18. data/lib/devise/models/authenticatable.rb +8 -0
  19. data/lib/devise/models/confirmable.rb +10 -6
  20. data/lib/devise/models/database_authenticatable.rb +9 -1
  21. data/lib/devise/models/recoverable.rb +6 -1
  22. data/lib/devise/models/rememberable.rb +36 -7
  23. data/lib/devise/models/token_authenticatable.rb +5 -5
  24. data/lib/devise/models/validatable.rb +1 -1
  25. data/lib/devise/path_checker.rb +7 -2
  26. data/lib/devise/rails.rb +6 -1
  27. data/lib/devise/rails/routes.rb +137 -50
  28. data/lib/devise/rails/warden_compat.rb +16 -2
  29. data/lib/devise/strategies/authenticatable.rb +12 -0
  30. data/lib/devise/strategies/base.rb +0 -18
  31. data/lib/devise/strategies/rememberable.rb +9 -1
  32. data/lib/devise/test_helpers.rb +2 -0
  33. data/lib/devise/version.rb +1 -1
  34. data/lib/generators/active_record/devise_generator.rb +28 -0
  35. data/lib/generators/{devise/devise → active_record}/templates/migration.rb +4 -0
  36. data/lib/generators/devise/devise_generator.rb +17 -0
  37. data/lib/generators/devise/{install/install_generator.rb → install_generator.rb} +1 -1
  38. data/lib/generators/devise/orm_helpers.rb +23 -0
  39. data/lib/generators/devise/{install/templates → templates}/README +0 -0
  40. data/lib/generators/devise/{install/templates → templates}/devise.rb +20 -13
  41. data/lib/generators/devise/{views/views_generator.rb → views_generator.rb} +2 -2
  42. data/lib/generators/mongoid/devise_generator.rb +17 -0
  43. data/test/controllers/helpers_test.rb +9 -0
  44. data/test/controllers/internal_helpers_test.rb +7 -16
  45. data/test/controllers/url_helpers_test.rb +11 -0
  46. data/test/encryptors_test.rb +1 -1
  47. data/test/failure_app_test.rb +18 -5
  48. data/test/integration/authenticatable_test.rb +76 -11
  49. data/test/integration/confirmable_test.rb +16 -9
  50. data/test/integration/lockable_test.rb +11 -13
  51. data/test/integration/registerable_test.rb +4 -4
  52. data/test/integration/rememberable_test.rb +54 -1
  53. data/test/mapping_test.rb +10 -45
  54. data/test/models/confirmable_test.rb +1 -1
  55. data/test/models/rememberable_test.rb +108 -0
  56. data/test/models/validatable_test.rb +2 -4
  57. data/test/models_test.rb +4 -4
  58. data/test/rails_app/app/active_record/admin.rb +1 -1
  59. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  60. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  61. data/test/rails_app/app/controllers/users_controller.rb +5 -1
  62. data/test/rails_app/app/mongoid/admin.rb +1 -1
  63. data/test/rails_app/config/application.rb +2 -2
  64. data/test/rails_app/config/environments/test.rb +2 -0
  65. data/test/rails_app/config/initializers/devise.rb +95 -34
  66. data/test/rails_app/config/routes.rb +32 -14
  67. data/test/routes_test.rb +34 -2
  68. data/test/support/integration.rb +22 -6
  69. data/test/test_helpers_test.rb +16 -2
  70. metadata +24 -27
  71. data/lib/devise/orm/data_mapper.rb +0 -97
  72. data/lib/generators/devise/devise/devise_generator.rb +0 -86
  73. data/lib/generators/devise_generator.rb +0 -2
  74. data/test/orm/data_mapper.rb +0 -10
  75. data/test/rails_app/app/data_mapper/admin.rb +0 -12
  76. data/test/rails_app/app/data_mapper/shim.rb +0 -2
  77. data/test/rails_app/app/data_mapper/user.rb +0 -23
@@ -1,6 +1,15 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class AuthenticationSanityTest < ActionController::IntegrationTest
4
+
5
+ def setup
6
+ Devise.sign_out_all_scopes = false
7
+ end
8
+
9
+ def teardown
10
+ Devise.sign_out_all_scopes = false
11
+ end
12
+
4
13
  test 'home should be accessible without sign in' do
5
14
  visit '/'
6
15
  assert_response :success
@@ -29,7 +38,7 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
29
38
  assert warden.authenticated?(:admin)
30
39
  end
31
40
 
32
- test 'sign out as user should not touch admin authentication' do
41
+ test 'sign out as user should not touch admin authentication if sign_out_all_scopes is false' do
33
42
  sign_in_as_user
34
43
  sign_in_as_admin
35
44
 
@@ -38,7 +47,7 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
38
47
  assert warden.authenticated?(:admin)
39
48
  end
40
49
 
41
- test 'sign out as admin should not touch user authentication' do
50
+ test 'sign out as admin should not touch user authentication if sign_out_all_scopes is false' do
42
51
  sign_in_as_user
43
52
  sign_in_as_admin
44
53
 
@@ -47,6 +56,26 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
47
56
  assert warden.authenticated?(:user)
48
57
  end
49
58
 
59
+ test 'sign out as user should also sign out admin if sign_out_all_scopes is true' do
60
+ Devise.sign_out_all_scopes = true
61
+ sign_in_as_user
62
+ sign_in_as_admin
63
+
64
+ get destroy_user_session_path
65
+ assert_not warden.authenticated?(:user)
66
+ assert_not warden.authenticated?(:admin)
67
+ end
68
+
69
+ test 'sign out as admin should also sign out user if sign_out_all_scopes is true' do
70
+ Devise.sign_out_all_scopes = true
71
+ sign_in_as_user
72
+ sign_in_as_admin
73
+
74
+ get destroy_admin_session_path
75
+ assert_not warden.authenticated?(:admin)
76
+ assert_not warden.authenticated?(:user)
77
+ end
78
+
50
79
  test 'not signed in as admin should not be able to access admins actions' do
51
80
  get admins_path
52
81
 
@@ -160,7 +189,7 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
160
189
  follow_redirect!
161
190
  sign_in_as_user :visit => false
162
191
 
163
- assert_template 'users/index'
192
+ assert_current_url '/users'
164
193
  assert_nil session[:"user_return_to"]
165
194
  end
166
195
 
@@ -176,7 +205,7 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
176
205
  follow_redirect!
177
206
  sign_in_as_user :visit => false
178
207
 
179
- assert_template 'users/index'
208
+ assert_current_url '/users'
180
209
  assert_nil session[:"user_return_to"]
181
210
  end
182
211
 
@@ -202,7 +231,7 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
202
231
  assert_redirected_to new_user_session_path
203
232
  end
204
233
 
205
- test 'allows session to be set by a given scope' do
234
+ test 'allows session to be set for a given scope' do
206
235
  sign_in_as_user
207
236
  get '/users'
208
237
  assert_equal "Cart", @controller.user_session[:cart]
@@ -249,12 +278,16 @@ class AuthenticationWithScopesTest < ActionController::IntegrationTest
249
278
  end
250
279
  end
251
280
 
252
- test 'uses the mapping from the default scope if specified' do
253
- swap Devise, :use_default_scope => true do
254
- get '/sign_in'
255
- assert_response :ok
256
- assert_contain 'Sign in'
257
- end
281
+ test 'uses the mapping from router' do
282
+ sign_in_as_user :visit => "/as/sign_in"
283
+ assert warden.authenticated?(:user)
284
+ assert_not warden.authenticated?(:admin)
285
+ end
286
+
287
+ test 'uses the mapping from nested devise_for call' do
288
+ sign_in_as_user :visit => "/devise_for/sign_in"
289
+ assert warden.authenticated?(:user)
290
+ assert_not warden.authenticated?(:admin)
258
291
  end
259
292
  end
260
293
 
@@ -276,4 +309,36 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
276
309
  get '/sign_in'
277
310
  end
278
311
  end
312
+
313
+ test 'sign in with script name' do
314
+ assert_nothing_raised do
315
+ get new_user_session_path, {}, "SCRIPT_NAME" => "/omg"
316
+ fill_in "email", "user@test.com"
317
+ end
318
+ end
319
+
320
+ test 'registration in xml format' do
321
+ assert_nothing_raised do
322
+ post user_registration_path(:format => 'xml', :user => {:email => "test@example.com", :password => "invalid"} )
323
+ end
324
+ end
325
+
326
+ test 'does not explode when invalid user class is stored in session' do
327
+ klass = User
328
+ paths = ActiveSupport::Dependencies.autoload_paths.dup
329
+
330
+ begin
331
+ sign_in_as_user
332
+ assert warden.authenticated?(:user)
333
+
334
+ Object.send :remove_const, :User
335
+ ActiveSupport::Dependencies.autoload_paths.clear
336
+
337
+ visit "/users"
338
+ assert_not warden.authenticated?(:user)
339
+ ensure
340
+ Object.const_set(:User, klass)
341
+ ActiveSupport::Dependencies.autoload_paths.replace(paths)
342
+ end
343
+ end
279
344
  end
@@ -16,16 +16,13 @@ class ConfirmationTest < ActionController::IntegrationTest
16
16
  fill_in 'email', :with => user.email
17
17
  click_button 'Resend confirmation instructions'
18
18
 
19
- assert_template 'sessions/new'
19
+ assert_current_url '/users/sign_in'
20
20
  assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
21
21
  assert_equal 1, ActionMailer::Base.deliveries.size
22
22
  end
23
23
 
24
24
  test 'user with invalid confirmation token should not be able to confirm an account' do
25
25
  visit_user_confirmation_with_token('invalid_confirmation')
26
-
27
- assert_response :success
28
- assert_template 'confirmations/new'
29
26
  assert_have_selector '#error_explanation'
30
27
  assert_contain /Confirmation token(.*)invalid/
31
28
  end
@@ -33,26 +30,36 @@ class ConfirmationTest < ActionController::IntegrationTest
33
30
  test 'user with valid confirmation token should be able to confirm an account' do
34
31
  user = create_user(:confirm => false)
35
32
  assert_not user.confirmed?
36
-
37
33
  visit_user_confirmation_with_token(user.confirmation_token)
38
34
 
39
- assert_template 'home/index'
40
35
  assert_contain 'Your account was successfully confirmed.'
41
-
36
+ assert_current_url '/'
42
37
  assert user.reload.confirmed?
43
38
  end
44
39
 
45
- test 'user already confirmed user should not be able to confirm the account again' do
40
+ test 'already confirmed user should not be able to confirm the account again' do
46
41
  user = create_user(:confirm => false)
47
42
  user.confirmed_at = Time.now
48
43
  user.save
49
44
  visit_user_confirmation_with_token(user.confirmation_token)
50
45
 
51
- assert_template 'confirmations/new'
52
46
  assert_have_selector '#error_explanation'
53
47
  assert_contain 'already confirmed'
54
48
  end
55
49
 
50
+ test 'already confirmed user should not be able to confirm the account again neither request confirmation' do
51
+ user = create_user(:confirm => false)
52
+ user.confirmed_at = Time.now
53
+ user.save
54
+
55
+ visit_user_confirmation_with_token(user.confirmation_token)
56
+ assert_contain 'already confirmed'
57
+
58
+ fill_in 'email', :with => user.email
59
+ click_button 'Resend confirmation instructions'
60
+ assert_contain 'already confirmed'
61
+ end
62
+
56
63
  test 'sign in user automatically after confirming it\'s email' do
57
64
  user = create_user(:confirm => false)
58
65
  visit_user_confirmation_with_token(user.confirmation_token)
@@ -37,27 +37,25 @@ class LockTest < ActionController::IntegrationTest
37
37
  end
38
38
 
39
39
  test 'unlocked pages should not be available if email strategy is disabled' do
40
- visit "/users/sign_in"
41
- click_link "Didn't receive unlock instructions?"
42
-
43
- swap Devise, :unlock_strategy => :time do
44
- visit "/users/sign_in"
40
+ visit "/admins/sign_in"
45
41
 
46
- assert_raise Webrat::NotFoundError do
47
- click_link "Didn't receive unlock instructions?"
48
- end
42
+ assert_raise Webrat::NotFoundError do
43
+ click_link "Didn't receive unlock instructions?"
44
+ end
49
45
 
50
- assert_raise AbstractController::ActionNotFound do
51
- visit new_user_unlock_path
52
- end
46
+ assert_raise NameError do
47
+ visit new_admin_unlock_path
53
48
  end
49
+
50
+ visit "/admins/unlock/new"
51
+ assert_response :not_found
54
52
  end
55
53
 
56
54
  test 'user with invalid unlock token should not be able to unlock an account' do
57
55
  visit_user_unlock_with_token('invalid_token')
58
56
 
59
57
  assert_response :success
60
- assert_template 'unlocks/new'
58
+ assert_current_url '/users/unlock?unlock_token=invalid_token'
61
59
  assert_have_selector '#error_explanation'
62
60
  assert_contain /Unlock token(.*)invalid/
63
61
  end
@@ -68,7 +66,7 @@ class LockTest < ActionController::IntegrationTest
68
66
 
69
67
  visit_user_unlock_with_token(user.unlock_token)
70
68
 
71
- assert_template 'home/index'
69
+ assert_current_url '/'
72
70
  assert_contain 'Your account was successfully unlocked.'
73
71
 
74
72
  assert_not user.reload.access_locked?
@@ -65,8 +65,8 @@ class RegistrationTest < ActionController::IntegrationTest
65
65
  fill_in 'password confirmation', :with => '123456'
66
66
  click_button 'Sign up'
67
67
 
68
- assert_template 'registrations/new'
69
- assert_contain 'Email has already been taken'
68
+ assert_current_url '/users'
69
+ assert_contain(/Email .* already .* taken/)
70
70
 
71
71
  assert_not warden.authenticated?(:user)
72
72
  end
@@ -92,7 +92,7 @@ class RegistrationTest < ActionController::IntegrationTest
92
92
  fill_in 'current password', :with => '123456'
93
93
  click_button 'Update'
94
94
 
95
- assert_template 'home/index'
95
+ assert_current_url '/'
96
96
  assert_contain 'You updated your account successfully.'
97
97
 
98
98
  assert_equal "user.new@email.com", User.first.email
@@ -122,7 +122,7 @@ class RegistrationTest < ActionController::IntegrationTest
122
122
  fill_in 'current password', :with => '123456'
123
123
  click_button 'Update'
124
124
 
125
- assert_template 'home/index'
125
+ assert_current_url '/'
126
126
  assert_contain 'You updated your account successfully.'
127
127
 
128
128
  assert User.first.valid_password?('pas123')
@@ -3,7 +3,6 @@ require 'test_helper'
3
3
  class RememberMeTest < ActionController::IntegrationTest
4
4
 
5
5
  def create_user_and_remember(add_to_token='')
6
- Devise.remember_for = 1
7
6
  user = create_user
8
7
  user.remember_me!
9
8
  raw_cookie = User.serialize_into_cookie(user).tap { |a| a.last << add_to_token }
@@ -17,6 +16,16 @@ class RememberMeTest < ActionController::IntegrationTest
17
16
  request.cookie_jar['raw_cookie']
18
17
  end
19
18
 
19
+ def signed_cookie(key)
20
+ controller.send(:cookies).signed[key]
21
+ end
22
+
23
+ def cookie_expires(key)
24
+ cookie = response.headers["Set-Cookie"].split("\n").grep(/^#{key}/).first
25
+ cookie.split(";").map(&:strip).grep(/^expires=/)
26
+ Time.parse($')
27
+ end
28
+
20
29
  test 'do not remember the user if he has not checked remember me option' do
21
30
  user = sign_in_as_user
22
31
  assert_nil request.cookies["remember_user_cookie"]
@@ -47,6 +56,50 @@ class RememberMeTest < ActionController::IntegrationTest
47
56
  assert warden.user(:user) == user
48
57
  end
49
58
 
59
+ test 'does not extend remember period through sign in' do
60
+ swap Devise, :extend_remember_period => true, :remember_for => 1.year do
61
+ user = create_user
62
+ user.remember_me!
63
+
64
+ user.remember_created_at = old = 10.days.ago
65
+ user.save
66
+
67
+ sign_in_as_user :remember_me => true
68
+ user.reload
69
+
70
+ assert warden.user(:user) == user
71
+ assert_equal old.to_i, user.remember_created_at.to_i
72
+ end
73
+ end
74
+
75
+ test 'if both extend_remember_period and remember_across_browsers are true, sends the same token with a new expire date' do
76
+ swap Devise, :remember_across_browsers => true, :extend_remember_period => true, :remember_for => 1.year do
77
+ user = create_user_and_remember
78
+ token = user.remember_token
79
+
80
+ user.remember_created_at = old = 10.minutes.ago
81
+ user.save!
82
+
83
+ get users_path
84
+ assert (cookie_expires("remember_user_token") - 1.year) > (old + 5.minutes)
85
+ assert_equal token, signed_cookie("remember_user_token").last
86
+ end
87
+ end
88
+
89
+ test 'if both extend_remember_period and remember_across_browsers are false, sends a new token with old expire date' do
90
+ swap Devise, :remember_across_browsers => false, :extend_remember_period => false, :remember_for => 1.year do
91
+ user = create_user_and_remember
92
+ token = user.remember_token
93
+
94
+ user.remember_created_at = old = 10.minutes.ago
95
+ user.save!
96
+
97
+ get users_path
98
+ assert (cookie_expires("remember_user_token") - 1.year) < (old + 5.minutes)
99
+ assert_not_equal token, signed_cookie("remember_user_token").last
100
+ end
101
+ end
102
+
50
103
  test 'do not remember other scopes' do
51
104
  user = create_user_and_remember
52
105
  get root_path
@@ -1,6 +1,12 @@
1
1
  require 'test_helper'
2
2
 
3
+ class FakeRequest < Struct.new(:path_info, :params)
4
+ end
5
+
3
6
  class MappingTest < ActiveSupport::TestCase
7
+ def fake_request(path, params={})
8
+ FakeRequest.new(path, params)
9
+ end
4
10
 
5
11
  test 'store options' do
6
12
  mapping = Devise.mappings[:user]
@@ -8,27 +14,15 @@ class MappingTest < ActiveSupport::TestCase
8
14
  assert_equal User.devise_modules, mapping.modules
9
15
  assert_equal :users, mapping.plural
10
16
  assert_equal :user, mapping.singular
11
- assert_equal :users, mapping.path
17
+ assert_equal "users", mapping.path
12
18
  end
13
19
 
14
20
  test 'allows path to be given' do
15
- assert_equal :admin_area, Devise.mappings[:admin].path
21
+ assert_equal "admin_area", Devise.mappings[:admin].path
16
22
  end
17
23
 
18
24
  test 'allows custom singular to be given' do
19
- assert_equal :accounts, Devise.mappings[:manager].path
20
- end
21
-
22
- test 'allows a controller depending on the mapping' do
23
- allowed = Devise.mappings[:user].allowed_controllers
24
- assert allowed.include?("devise/sessions")
25
- assert allowed.include?("devise/confirmations")
26
- assert allowed.include?("devise/passwords")
27
-
28
- allowed = Devise.mappings[:admin].allowed_controllers
29
- assert allowed.include?("sessions")
30
- assert_not allowed.include?("devise/confirmations")
31
- assert_not allowed.include?("devise/unlocks")
25
+ assert_equal "accounts", Devise.mappings[:manager].path
32
26
  end
33
27
 
34
28
  test 'has strategies depending on the model declaration' do
@@ -36,15 +30,6 @@ class MappingTest < ActiveSupport::TestCase
36
30
  assert_equal [:database_authenticatable], Devise.mappings[:admin].strategies
37
31
  end
38
32
 
39
- test 'find mapping by path' do
40
- assert_nil Devise::Mapping.find_by_path("/foo/bar")
41
- assert_equal Devise.mappings[:user], Devise::Mapping.find_by_path("/users/session")
42
- end
43
-
44
- test 'find mapping by customized path' do
45
- assert_equal Devise.mappings[:admin], Devise::Mapping.find_by_path("/admin_area/session")
46
- end
47
-
48
33
  test 'find scope for a given object' do
49
34
  assert_equal :user, Devise::Mapping.find_scope!(User)
50
35
  assert_equal :user, Devise::Mapping.find_scope!(:user)
@@ -82,26 +67,6 @@ class MappingTest < ActiveSupport::TestCase
82
67
  assert_equal 'unblock', mapping.path_names[:unlock]
83
68
  end
84
69
 
85
- test 'has an empty path as default path prefix' do
86
- mapping = Devise.mappings[:user]
87
- assert_equal '/', mapping.path_prefix
88
- end
89
-
90
- test 'allow path prefix to be configured' do
91
- mapping = Devise.mappings[:manager]
92
- assert_equal '/:locale/', mapping.path_prefix
93
- end
94
-
95
- test 'retrieve as from the proper position' do
96
- assert_equal 1, Devise.mappings[:user].segment_position
97
- assert_equal 2, Devise.mappings[:manager].segment_position
98
- end
99
-
100
- test 'path is returned with path prefix and as' do
101
- assert_equal '/users', Devise.mappings[:user].full_path
102
- assert_equal '/:locale/accounts', Devise.mappings[:manager].full_path
103
- end
104
-
105
70
  test 'magic predicates' do
106
71
  mapping = Devise.mappings[:user]
107
72
  assert mapping.authenticatable?
@@ -113,8 +78,8 @@ class MappingTest < ActiveSupport::TestCase
113
78
  mapping = Devise.mappings[:admin]
114
79
  assert mapping.authenticatable?
115
80
  assert mapping.recoverable?
81
+ assert mapping.lockable?
116
82
  assert_not mapping.confirmable?
117
- assert_not mapping.lockable?
118
83
  assert_not mapping.rememberable?
119
84
  end
120
85
  end