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
@@ -1,6 +1,28 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class DatabaseAuthenticationTest < ActionController::IntegrationTest
4
+ test 'sign in with email of different case should succeed when email is in the list of case insensitive keys' do
5
+ create_user(:email => 'Foo@Bar.com')
6
+
7
+ sign_in_as_user do
8
+ fill_in 'email', :with => 'foo@bar.com'
9
+ end
10
+
11
+ assert warden.authenticated?(:user)
12
+ end
13
+
14
+ test 'sign in with email of different case should fail when email is NOT the list of case insensitive keys' do
15
+ swap Devise, :case_insensitive_keys => [] do
16
+ create_user(:email => 'Foo@Bar.com')
17
+
18
+ sign_in_as_user do
19
+ fill_in 'email', :with => 'foo@bar.com'
20
+ end
21
+
22
+ assert_not warden.authenticated?(:user)
23
+ end
24
+ end
25
+
4
26
  test 'sign in should not authenticate if not using proper authentication keys' do
5
27
  swap Devise, :authentication_keys => [:username] do
6
28
  sign_in_as_user
@@ -47,6 +47,16 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
47
47
  end
48
48
  end
49
49
 
50
+ test 'sign in should authenticate with really long token' do
51
+ token = "token_containing_so_many_characters_that_the_base64_encoding_will_wrap"
52
+ user = create_user
53
+ user.update_attribute :authentication_token, token
54
+ get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{ActiveSupport::Base64.encode64("#{token}:x")}"
55
+ assert_response :success
56
+ assert_match "<email>user@test.com</email>", response.body
57
+ assert warden.authenticated?(:user)
58
+ end
59
+
50
60
  private
51
61
 
52
62
  def sign_in_as_new_user_with_http(username="user@test.com", password="123456")
@@ -54,11 +64,11 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
54
64
  get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{ActiveSupport::Base64.encode64("#{username}:#{password}")}"
55
65
  user
56
66
  end
57
-
67
+
58
68
  # Sign in with oauth2 token. This is just to test that it isn't misinterpreted as basic authentication
59
69
  def add_oauth2_header
60
70
  user = create_user
61
71
  get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "OAuth #{ActiveSupport::Base64.encode64("#{user.email}:123456")}"
62
72
  end
63
73
 
64
- end
74
+ end
@@ -0,0 +1,138 @@
1
+ require 'test_helper'
2
+
3
+ class OmniauthableIntegrationTest < ActionController::IntegrationTest
4
+ FACEBOOK_INFO = {
5
+ "id" => '12345',
6
+ "link" => 'http://facebook.com/josevalim',
7
+ "email" => 'user@example.com',
8
+ "first_name" => 'Jose',
9
+ "last_name" => 'Valim',
10
+ "website" => 'http://blog.plataformatec.com.br'
11
+ }
12
+
13
+ setup do
14
+ OmniAuth.config.test_mode = true
15
+ stub_facebook!
16
+ end
17
+
18
+ teardown do
19
+ OmniAuth.config.test_mode = false
20
+ end
21
+
22
+ def stub_facebook!
23
+ OmniAuth.config.mock_auth[:facebook] = {
24
+ "uid" => '12345',
25
+ "provider" => 'facebook',
26
+ "user_info" => {"nickname" => 'josevalim'},
27
+ "credentials" => {"token" => 'plataformatec'},
28
+ "extra" => {"user_hash" => FACEBOOK_INFO}
29
+ }
30
+ end
31
+
32
+ def stub_action!(name)
33
+ Users::OmniauthCallbacksController.class_eval do
34
+ alias_method :__old_facebook, :facebook
35
+ alias_method :facebook, name
36
+ end
37
+ yield
38
+ ensure
39
+ Users::OmniauthCallbacksController.class_eval do
40
+ alias_method :facebook, :__old_facebook
41
+ end
42
+ end
43
+
44
+ test "can access omniauth.auth in the env hash" do
45
+ visit "/users/sign_in"
46
+ click_link "Sign in with Facebook"
47
+
48
+ json = ActiveSupport::JSON.decode(response.body)
49
+
50
+ assert_equal "12345", json["uid"]
51
+ assert_equal "facebook", json["provider"]
52
+ assert_equal "josevalim", json["user_info"]["nickname"]
53
+ assert_equal FACEBOOK_INFO, json["extra"]["user_hash"]
54
+ assert_equal "plataformatec", json["credentials"]["token"]
55
+ end
56
+
57
+ test "cleans up session on sign up" do
58
+ assert_no_difference "User.count" do
59
+ visit "/users/sign_in"
60
+ click_link "Sign in with Facebook"
61
+ end
62
+
63
+ assert session["devise.facebook_data"]
64
+
65
+ assert_difference "User.count" do
66
+ visit "/users/sign_up"
67
+ fill_in "Password", :with => "123456"
68
+ fill_in "Password confirmation", :with => "123456"
69
+ click_button "Sign up"
70
+ end
71
+
72
+ assert_current_url "/"
73
+ assert_contain "You have signed up successfully."
74
+ assert_contain "Hello User user@example.com"
75
+ assert_not session["devise.facebook_data"]
76
+ end
77
+
78
+ test "cleans up session on cancel" do
79
+ assert_no_difference "User.count" do
80
+ visit "/users/sign_in"
81
+ click_link "Sign in with Facebook"
82
+ end
83
+
84
+ assert session["devise.facebook_data"]
85
+ visit "/users/cancel"
86
+ assert !session["devise.facebook_data"]
87
+ end
88
+
89
+ test "cleans up session on sign in" do
90
+ assert_no_difference "User.count" do
91
+ visit "/users/sign_in"
92
+ click_link "Sign in with Facebook"
93
+ end
94
+
95
+ assert session["devise.facebook_data"]
96
+ user = sign_in_as_user
97
+ assert !session["devise.facebook_data"]
98
+ end
99
+
100
+ test "sign in and send remember token if configured" do
101
+ visit "/users/sign_in"
102
+ click_link "Sign in with Facebook"
103
+ assert_nil warden.cookies["remember_user_token"]
104
+
105
+ stub_action!(:sign_in_facebook) do
106
+ create_user
107
+ visit "/users/sign_in"
108
+ click_link "Sign in with Facebook"
109
+ assert warden.authenticated?(:user)
110
+ assert warden.cookies["remember_user_token"]
111
+ end
112
+ end
113
+
114
+ test "generates a proper link when SCRIPT_NAME is set" do
115
+ header 'SCRIPT_NAME', '/q'
116
+ visit "/users/sign_in"
117
+ click_link "Sign in with Facebook"
118
+
119
+ assert_equal '/q/users/auth/facebook', current_url
120
+ end
121
+
122
+ test "handles callback error parameter according to the specification" do
123
+ OmniAuth.config.mock_auth[:facebook] = :access_denied
124
+ visit "/users/auth/facebook/callback?error=access_denied"
125
+ assert_current_url "/users/sign_in"
126
+ assert_contain 'Could not authorize you from Facebook because "Access denied".'
127
+ end
128
+
129
+ test "handles other exceptions from omniauth" do
130
+ OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
131
+
132
+ visit "/users/sign_in"
133
+ click_link "Sign in with facebook"
134
+
135
+ assert_current_url "/users/sign_in"
136
+ assert_contain 'Could not authorize you from Facebook because "Invalid credentials".'
137
+ end
138
+ end
@@ -9,9 +9,7 @@ class PasswordTest < ActionController::IntegrationTest
9
9
 
10
10
  def request_forgot_password(&block)
11
11
  visit_new_password_path
12
-
13
12
  assert_response :success
14
- assert_template 'passwords/new'
15
13
  assert_not warden.authenticated?(:user)
16
14
 
17
15
  fill_in 'email', :with => 'user@test.com'
@@ -19,19 +17,42 @@ class PasswordTest < ActionController::IntegrationTest
19
17
  click_button 'Send me reset password instructions'
20
18
  end
21
19
 
22
- def reset_password(options={}, &block)
23
- unless options[:visit] == false
24
- visit edit_user_password_path(:reset_password_token => options[:reset_password_token])
25
- end
20
+ def reset_password(options={}, &block)
21
+ visit edit_user_password_path(:reset_password_token => options[:reset_password_token]) unless options[:visit] == false
26
22
  assert_response :success
27
- assert_template 'passwords/edit'
28
23
 
29
- fill_in 'Password', :with => '987654321'
30
- fill_in 'Password confirmation', :with => '987654321'
24
+ fill_in 'New password', :with => '987654321'
25
+ fill_in 'Confirm new password', :with => '987654321'
31
26
  yield if block_given?
32
27
  click_button 'Change my password'
33
28
  end
34
29
 
30
+ test 'reset password with email of different case should succeed when email is in the list of case insensitive keys' do
31
+ create_user(:email => 'Foo@Bar.com')
32
+
33
+ request_forgot_password do
34
+ fill_in 'email', :with => 'foo@bar.com'
35
+ end
36
+
37
+ assert_current_url '/users/sign_in'
38
+ assert_contain 'You will receive an email with instructions about how to reset your password in a few minutes.'
39
+ end
40
+
41
+ test 'reset password with email of different case should fail when email is NOT the list of case insensitive keys' do
42
+ swap Devise, :case_insensitive_keys => [] do
43
+ create_user(:email => 'Foo@Bar.com')
44
+
45
+ request_forgot_password do
46
+ fill_in 'email', :with => 'foo@bar.com'
47
+ end
48
+
49
+ assert_response :success
50
+ assert_current_url '/users/password'
51
+ assert_have_selector "input[type=email][value='foo@bar.com']"
52
+ assert_contain 'not found'
53
+ end
54
+ end
55
+
35
56
  test 'authenticated user should not be able to visit forgot password page' do
36
57
  sign_in_as_user
37
58
  assert warden.authenticated?(:user)
@@ -46,7 +67,7 @@ class PasswordTest < ActionController::IntegrationTest
46
67
  create_user
47
68
  request_forgot_password
48
69
 
49
- assert_template 'sessions/new'
70
+ assert_current_url '/users/sign_in'
50
71
  assert_contain 'You will receive an email with instructions about how to reset your password in a few minutes.'
51
72
  end
52
73
 
@@ -56,16 +77,14 @@ class PasswordTest < ActionController::IntegrationTest
56
77
  end
57
78
 
58
79
  assert_response :success
59
- assert_template 'passwords/new'
60
- assert_have_selector 'input[type=text][value=\'invalid.test@test.com\']'
61
- assert_contain 'Email not found'
80
+ assert_current_url '/users/password'
81
+ assert_have_selector "input[type=email][value='invalid.test@test.com']"
82
+ assert_contain 'not found'
62
83
  end
63
84
 
64
85
  test 'authenticated user should not be able to visit edit password page' do
65
86
  sign_in_as_user
66
-
67
87
  get edit_user_password_path
68
-
69
88
  assert_response :redirect
70
89
  assert_redirected_to root_path
71
90
  assert warden.authenticated?(:user)
@@ -76,7 +95,7 @@ class PasswordTest < ActionController::IntegrationTest
76
95
  reset_password :reset_password_token => 'invalid_reset_password'
77
96
 
78
97
  assert_response :success
79
- assert_template 'passwords/edit'
98
+ assert_current_url '/users/password'
80
99
  assert_have_selector '#error_explanation'
81
100
  assert_contain /Reset password token(.*)invalid/
82
101
  assert_not user.reload.valid_password?('987654321')
@@ -86,11 +105,11 @@ class PasswordTest < ActionController::IntegrationTest
86
105
  user = create_user
87
106
  request_forgot_password
88
107
  reset_password :reset_password_token => user.reload.reset_password_token do
89
- fill_in 'Password confirmation', :with => 'other_password'
108
+ fill_in 'Confirm new password', :with => 'other_password'
90
109
  end
91
110
 
92
111
  assert_response :success
93
- assert_template 'passwords/edit'
112
+ assert_current_url '/users/password'
94
113
  assert_have_selector '#error_explanation'
95
114
  assert_contain 'Password doesn\'t match confirmation'
96
115
  assert_not user.reload.valid_password?('987654321')
@@ -101,7 +120,7 @@ class PasswordTest < ActionController::IntegrationTest
101
120
  request_forgot_password
102
121
  reset_password :reset_password_token => user.reload.reset_password_token
103
122
 
104
- assert_template 'home/index'
123
+ assert_current_url '/'
105
124
  assert_contain 'Your password was changed successfully.'
106
125
  assert user.reload.valid_password?('987654321')
107
126
  end
@@ -110,7 +129,7 @@ class PasswordTest < ActionController::IntegrationTest
110
129
  user = create_user
111
130
  request_forgot_password
112
131
  reset_password :reset_password_token => user.reload.reset_password_token do
113
- fill_in 'Password confirmation', :with => 'other_password'
132
+ fill_in 'Confirm new password', :with => 'other_password'
114
133
  end
115
134
  assert_response :success
116
135
  assert_have_selector '#error_explanation'
@@ -13,13 +13,29 @@ class RegistrationTest < ActionController::IntegrationTest
13
13
  fill_in 'password confirmation', :with => 'new_user123'
14
14
  click_button 'Sign up'
15
15
 
16
- assert_contain 'You have signed up successfully.'
16
+ assert_contain 'Welcome! You have signed up successfully.'
17
17
  assert warden.authenticated?(:admin)
18
+ assert_current_url "/admin_area/home"
18
19
 
19
20
  admin = Admin.last :order => "id"
20
21
  assert_equal admin.email, 'new_user@test.com'
21
22
  end
22
23
 
24
+ test 'a guest admin should be able to sign in and be redirected to a custom location' do
25
+ Devise::RegistrationsController.any_instance.stubs(:after_sign_up_path_for).returns("/?custom=1")
26
+ get new_admin_session_path
27
+ click_link 'Sign up'
28
+
29
+ fill_in 'email', :with => 'new_user@test.com'
30
+ fill_in 'password', :with => 'new_user123'
31
+ fill_in 'password confirmation', :with => 'new_user123'
32
+ click_button 'Sign up'
33
+
34
+ assert_contain 'Welcome! You have signed up successfully.'
35
+ assert warden.authenticated?(:admin)
36
+ assert_current_url "/?custom=1"
37
+ end
38
+
23
39
  test 'a guest user should be able to sign up successfully and be blocked by confirmation' do
24
40
  get new_user_registration_path
25
41
 
@@ -28,9 +44,9 @@ class RegistrationTest < ActionController::IntegrationTest
28
44
  fill_in 'password confirmation', :with => 'new_user123'
29
45
  click_button 'Sign up'
30
46
 
31
- assert_contain 'You have signed up successfully'
32
- assert_contain 'Sign in'
47
+ assert_contain 'You have signed up successfully. However, we could not sign you in because your account is unconfirmed.'
33
48
  assert_not_contain 'You have to confirm your account before continuing'
49
+ assert_current_url "/"
34
50
 
35
51
  assert_not warden.authenticated?(:user)
36
52
 
@@ -39,6 +55,19 @@ class RegistrationTest < ActionController::IntegrationTest
39
55
  assert_not user.confirmed?
40
56
  end
41
57
 
58
+ test 'a guest user should be blocked by confirmation and redirected to a custom path' do
59
+ Devise::RegistrationsController.any_instance.stubs(:after_inactive_sign_up_path_for).returns("/?custom=1")
60
+ get new_user_registration_path
61
+
62
+ fill_in 'email', :with => 'new_user@test.com'
63
+ fill_in 'password', :with => 'new_user123'
64
+ fill_in 'password confirmation', :with => 'new_user123'
65
+ click_button 'Sign up'
66
+
67
+ assert_current_url "/?custom=1"
68
+ assert_not warden.authenticated?(:user)
69
+ end
70
+
42
71
  test 'a guest user cannot sign up with invalid information' do
43
72
  get new_user_registration_path
44
73
 
@@ -51,6 +80,7 @@ class RegistrationTest < ActionController::IntegrationTest
51
80
  assert_have_selector '#error_explanation'
52
81
  assert_contain "Email is invalid"
53
82
  assert_contain "Password doesn't match confirmation"
83
+ assert_contain "2 errors prohibited"
54
84
  assert_nil User.first
55
85
 
56
86
  assert_not warden.authenticated?(:user)
@@ -66,7 +96,7 @@ class RegistrationTest < ActionController::IntegrationTest
66
96
  click_button 'Sign up'
67
97
 
68
98
  assert_current_url '/users'
69
- assert_contain(/Email .* already.*taken/)
99
+ assert_contain(/Email.*already.*taken/)
70
100
 
71
101
  assert_not warden.authenticated?(:user)
72
102
  end
@@ -98,6 +128,20 @@ class RegistrationTest < ActionController::IntegrationTest
98
128
  assert_equal "user.new@email.com", User.first.email
99
129
  end
100
130
 
131
+ test 'a signed in user should still be able to use the website after changing his password' do
132
+ sign_in_as_user
133
+ get edit_user_registration_path
134
+
135
+ fill_in 'password', :with => '12345678'
136
+ fill_in 'password confirmation', :with => '12345678'
137
+ fill_in 'current password', :with => '123456'
138
+ click_button 'Update'
139
+
140
+ assert_contain 'You updated your account successfully.'
141
+ get users_path
142
+ assert warden.authenticated?(:user)
143
+ end
144
+
101
145
  test 'a signed in user should not change his current user with invalid password' do
102
146
  sign_in_as_user
103
147
  get edit_user_registration_path
@@ -150,4 +194,16 @@ class RegistrationTest < ActionController::IntegrationTest
150
194
 
151
195
  assert User.all.empty?
152
196
  end
197
+
198
+ test 'a user should be able to cancel sign up by deleting data in the session' do
199
+ get "/set"
200
+ assert_equal "something", @request.session["devise.foo_bar"]
201
+
202
+ get "/users/sign_up"
203
+ assert_equal "something", @request.session["devise.foo_bar"]
204
+
205
+ get "/users/cancel"
206
+ assert_nil @request.session["devise.foo_bar"]
207
+ assert_redirected_to new_user_registration_path
208
+ end
153
209
  end
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class RememberMeTest < ActionController::IntegrationTest
4
-
5
4
  def create_user_and_remember(add_to_token='')
6
5
  user = create_user
7
6
  user.remember_me!
@@ -10,6 +9,14 @@ class RememberMeTest < ActionController::IntegrationTest
10
9
  user
11
10
  end
12
11
 
12
+ def create_admin_and_remember
13
+ admin = create_admin
14
+ admin.remember_me!
15
+ raw_cookie = Admin.serialize_into_cookie(admin)
16
+ cookies['remember_admin_token'] = generate_signed_cookie(raw_cookie)
17
+ admin
18
+ end
19
+
13
20
  def generate_signed_cookie(raw_cookie)
14
21
  request = ActionDispatch::TestRequest.new
15
22
  request.cookie_jar.signed['raw_cookie'] = raw_cookie
@@ -21,39 +28,58 @@ class RememberMeTest < ActionController::IntegrationTest
21
28
  end
22
29
 
23
30
  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($')
31
+ cookie = response.headers["Set-Cookie"].split("\n").grep(/^#{key}/).first
32
+ expires = cookie.split(";").map(&:strip).grep(/^expires=/).first
33
+ Time.parse(expires).utc
27
34
  end
28
35
 
29
36
  test 'do not remember the user if he has not checked remember me option' do
30
37
  user = sign_in_as_user
31
38
  assert_nil request.cookies["remember_user_cookie"]
32
- assert_nil user.reload.remember_token
33
39
  end
34
40
 
35
41
  test 'generate remember token after sign in' do
36
42
  user = sign_in_as_user :remember_me => true
37
43
  assert request.cookies["remember_user_token"]
38
- assert user.reload.remember_token
39
44
  end
40
45
 
41
- test 'generate remember token after sign in setting cookie domain' do
46
+ test 'generate remember token after sign in setting cookie options' do
42
47
  # We test this by asserting the cookie is not sent after the redirect
43
48
  # since we changed the domain. This is the only difference with the
44
49
  # previous test.
45
- swap User, :cookie_domain => "omg.somewhere.com" do
50
+ swap Devise, :cookie_options => { :domain => "omg.somewhere.com" } do
46
51
  user = sign_in_as_user :remember_me => true
47
52
  assert_nil request.cookies["remember_user_token"]
48
53
  end
49
54
  end
50
55
 
56
+ test 'generate remember token after sign in setting session options' do
57
+ begin
58
+ Rails.configuration.session_options[:domain] = "omg.somewhere.com"
59
+ user = sign_in_as_user :remember_me => true
60
+ assert_nil request.cookies["remember_user_token"]
61
+ ensure
62
+ Rails.configuration.session_options.delete(:domain)
63
+ end
64
+ end
65
+
51
66
  test 'remember the user before sign in' do
52
67
  user = create_user_and_remember
53
68
  get users_path
54
69
  assert_response :success
55
70
  assert warden.authenticated?(:user)
56
71
  assert warden.user(:user) == user
72
+ assert_match /remember_user_token[^\n]*HttpOnly\n/, response.headers["Set-Cookie"], "Expected Set-Cookie header in response to set HttpOnly flag on remember_user_token cookie."
73
+ end
74
+
75
+ test 'cookies are destroyed on unverified requests' do
76
+ swap ApplicationController, :allow_forgery_protection => true do
77
+ user = create_user_and_remember
78
+ get users_path
79
+ assert warden.authenticated?(:user)
80
+ post root_path, :authenticity_token => 'INVALID'
81
+ assert_not warden.authenticated?(:user)
82
+ end
57
83
  end
58
84
 
59
85
  test 'does not extend remember period through sign in' do
@@ -74,29 +100,29 @@ class RememberMeTest < ActionController::IntegrationTest
74
100
 
75
101
  test 'if both extend_remember_period and remember_across_browsers are true, sends the same token with a new expire date' do
76
102
  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
103
+ admin = create_admin_and_remember
104
+ token = admin.remember_token
79
105
 
80
- user.remember_created_at = old = 10.minutes.ago
81
- user.save!
106
+ admin.remember_created_at = old = 10.minutes.ago
107
+ admin.save!
82
108
 
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
109
+ get root_path
110
+ assert (cookie_expires("remember_admin_token") - 1.year) > (old + 5.minutes)
111
+ assert_equal token, signed_cookie("remember_admin_token").last
86
112
  end
87
113
  end
88
114
 
89
115
  test 'if both extend_remember_period and remember_across_browsers are false, sends a new token with old expire date' do
90
116
  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
117
+ admin = create_admin_and_remember
118
+ token = admin.remember_token
93
119
 
94
- user.remember_created_at = old = 10.minutes.ago
95
- user.save!
120
+ admin.remember_created_at = old = 10.minutes.ago
121
+ admin.save!
96
122
 
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
123
+ get root_path
124
+ assert (cookie_expires("remember_admin_token") - 1.year) < (old + 5.minutes)
125
+ assert_not_equal token, signed_cookie("remember_admin_token").last
100
126
  end
101
127
  end
102
128
 
@@ -124,23 +150,40 @@ class RememberMeTest < ActionController::IntegrationTest
124
150
  end
125
151
  end
126
152
 
127
- test 'forget the user before sign out' do
153
+ test 'do not remember the user anymore after forget' do
128
154
  user = create_user_and_remember
129
155
  get users_path
130
156
  assert warden.authenticated?(:user)
157
+
131
158
  get destroy_user_session_path
132
159
  assert_not warden.authenticated?(:user)
133
- assert_nil user.reload.remember_token
134
160
  assert_nil warden.cookies['remember_user_token']
161
+
162
+ get users_path
163
+ assert_not warden.authenticated?(:user)
135
164
  end
136
165
 
137
- test 'do not remember the user anymore after forget' do
166
+ test 'do not remember the admin anymore after forget' do
167
+ admin = create_admin_and_remember
168
+ get root_path
169
+ assert warden.authenticated?(:admin)
170
+
171
+ get destroy_admin_session_path
172
+ assert_not warden.authenticated?(:admin)
173
+ assert_nil admin.reload.remember_token
174
+ assert_nil warden.cookies['remember_admin_token']
175
+
176
+ get root_path
177
+ assert_not warden.authenticated?(:admin)
178
+ end
179
+
180
+ test 'changing user password expires remember me token' do
138
181
  user = create_user_and_remember
139
- get users_path
140
- assert warden.authenticated?(:user)
141
- get destroy_user_session_path
182
+ user.password = "another_password"
183
+ user.password_confirmation = "another_password"
184
+ user.save!
185
+
142
186
  get users_path
143
187
  assert_not warden.authenticated?(:user)
144
- assert_nil warden.cookies['remember_user_token']
145
188
  end
146
189
  end
@@ -76,5 +76,14 @@ class SessionTimeoutTest < ActionController::IntegrationTest
76
76
  assert_contain 'Session expired!'
77
77
  end
78
78
  end
79
-
79
+
80
+ test 'time out not triggered if remembered' do
81
+ user = sign_in_as_user :remember_me => true
82
+ get expire_user_path(user)
83
+ assert_not_nil last_request_at
84
+
85
+ get users_path
86
+ assert_response :success
87
+ assert warden.authenticated?(:user)
88
+ end
80
89
  end