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.
- data/.gitignore +10 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.rdoc +94 -0
- data/Gemfile +24 -13
- data/Gemfile.lock +119 -75
- data/MIT-LICENSE +1 -1
- data/README.rdoc +144 -101
- data/Rakefile +3 -24
- data/app/controllers/devise/confirmations_controller.rb +1 -1
- data/app/controllers/devise/omniauth_callbacks_controller.rb +26 -0
- data/app/controllers/devise/passwords_controller.rb +1 -1
- data/app/controllers/devise/registrations_controller.rb +60 -7
- data/app/controllers/devise/sessions_controller.rb +6 -4
- data/app/controllers/devise/unlocks_controller.rb +1 -1
- data/app/helpers/devise_helper.rb +10 -2
- data/app/mailers/devise/mailer.rb +27 -10
- data/app/views/devise/confirmations/new.html.erb +1 -1
- data/app/views/devise/passwords/edit.html.erb +2 -2
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/edit.html.erb +1 -1
- data/app/views/devise/registrations/new.html.erb +1 -1
- data/app/views/devise/sessions/new.html.erb +1 -1
- data/app/views/devise/shared/_links.erb +6 -0
- data/app/views/devise/unlocks/new.html.erb +1 -1
- data/config/locales/en.yml +11 -2
- data/devise.gemspec +25 -0
- data/lib/devise/controllers/helpers.rb +119 -116
- data/lib/devise/controllers/internal_helpers.rb +29 -8
- data/lib/devise/controllers/rememberable.rb +52 -0
- data/lib/devise/controllers/scoped_views.rb +4 -6
- data/lib/devise/controllers/url_helpers.rb +3 -5
- data/lib/devise/encryptors/authlogic_sha512.rb +1 -1
- data/lib/devise/encryptors/base.rb +1 -1
- data/lib/devise/encryptors/restful_authentication_sha1.rb +4 -4
- data/lib/devise/failure_app.rb +46 -10
- data/lib/devise/hooks/activatable.rb +2 -2
- data/lib/devise/hooks/forgetable.rb +1 -3
- data/lib/devise/hooks/rememberable.rb +5 -42
- data/lib/devise/hooks/timeoutable.rb +1 -1
- data/lib/devise/mapping.rb +18 -7
- data/lib/devise/models/authenticatable.rb +73 -31
- data/lib/devise/models/confirmable.rb +16 -20
- data/lib/devise/models/database_authenticatable.rb +27 -37
- data/lib/devise/models/encryptable.rb +72 -0
- data/lib/devise/models/lockable.rb +27 -21
- data/lib/devise/models/omniauthable.rb +23 -0
- data/lib/devise/models/recoverable.rb +13 -3
- data/lib/devise/models/registerable.rb +13 -0
- data/lib/devise/models/rememberable.rb +39 -34
- data/lib/devise/models/timeoutable.rb +20 -3
- data/lib/devise/models/token_authenticatable.rb +22 -10
- data/lib/devise/models/validatable.rb +16 -4
- data/lib/devise/models.rb +4 -16
- data/lib/devise/modules.rb +15 -8
- data/lib/devise/omniauth/config.rb +18 -0
- data/lib/devise/omniauth/url_helpers.rb +33 -0
- data/lib/devise/omniauth.rb +32 -0
- data/lib/devise/orm/active_record.rb +2 -0
- data/lib/devise/orm/mongoid.rb +4 -2
- data/lib/devise/rails/routes.rb +67 -20
- data/lib/devise/rails/warden_compat.rb +101 -15
- data/lib/devise/rails.rb +33 -44
- data/lib/devise/schema.rb +16 -16
- data/lib/devise/strategies/authenticatable.rb +48 -7
- data/lib/devise/strategies/database_authenticatable.rb +1 -1
- data/lib/devise/strategies/rememberable.rb +6 -5
- data/lib/devise/strategies/token_authenticatable.rb +6 -2
- data/lib/devise/test_helpers.rb +13 -3
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +162 -50
- data/lib/generators/active_record/devise_generator.rb +2 -2
- data/lib/generators/active_record/templates/migration.rb +2 -0
- data/lib/generators/devise/devise_generator.rb +3 -1
- data/lib/generators/devise/orm_helpers.rb +1 -1
- data/lib/generators/devise/views_generator.rb +8 -45
- data/lib/generators/mongoid/devise_generator.rb +2 -2
- data/lib/generators/templates/devise.rb +82 -39
- data/test/controllers/helpers_test.rb +78 -72
- data/test/controllers/internal_helpers_test.rb +29 -8
- data/test/controllers/url_helpers_test.rb +2 -1
- data/test/devise_test.rb +10 -0
- data/test/failure_app_test.rb +86 -22
- data/test/generators/active_record_generator_test.rb +24 -0
- data/test/generators/devise_generator_test.rb +33 -0
- data/test/generators/install_generator_test.rb +13 -0
- data/test/generators/mongoid_generator_test.rb +22 -0
- data/test/generators/views_generator_test.rb +35 -0
- data/test/indifferent_hash.rb +33 -0
- data/test/integration/authenticatable_test.rb +165 -62
- data/test/integration/database_authenticatable_test.rb +22 -0
- data/test/integration/http_authenticatable_test.rb +12 -2
- data/test/integration/omniauthable_test.rb +138 -0
- data/test/integration/recoverable_test.rb +39 -20
- data/test/integration/registerable_test.rb +60 -4
- data/test/integration/rememberable_test.rb +72 -29
- data/test/integration/timeoutable_test.rb +10 -1
- data/test/integration/token_authenticatable_test.rb +55 -6
- data/test/mailers/confirmation_instructions_test.rb +4 -0
- data/test/mailers/reset_password_instructions_test.rb +4 -0
- data/test/mailers/unlock_instructions_test.rb +4 -0
- data/test/mapping_test.rb +37 -3
- data/test/models/confirmable_test.rb +32 -15
- data/test/models/database_authenticatable_test.rb +14 -71
- data/test/models/encryptable_test.rb +65 -0
- data/test/models/lockable_test.rb +48 -11
- data/test/models/recoverable_test.rb +28 -2
- data/test/models/rememberable_test.rb +186 -125
- data/test/models/token_authenticatable_test.rb +19 -1
- data/test/models_test.rb +12 -5
- data/test/omniauth/url_helpers_test.rb +54 -0
- data/test/orm/mongoid.rb +3 -2
- data/test/rails_app/Rakefile +10 -0
- data/test/rails_app/app/active_record/admin.rb +4 -1
- data/test/rails_app/app/active_record/user.rb +5 -4
- data/test/rails_app/app/controllers/{sessions_controller.rb → admins/sessions_controller.rb} +1 -1
- data/test/rails_app/app/controllers/application_controller.rb +0 -1
- data/test/rails_app/app/controllers/home_controller.rb +9 -0
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
- data/test/rails_app/app/mongoid/admin.rb +4 -1
- data/test/rails_app/app/mongoid/shim.rb +16 -3
- data/test/rails_app/app/mongoid/user.rb +5 -5
- data/test/rails_app/app/views/admins/index.html.erb +1 -0
- data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
- data/test/rails_app/app/views/home/index.html.erb +1 -0
- data/test/rails_app/app/views/home/private.html.erb +1 -0
- data/test/rails_app/app/views/layouts/application.html.erb +24 -0
- data/test/rails_app/app/views/users/index.html.erb +1 -0
- data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
- data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
- data/test/rails_app/config/application.rb +5 -0
- data/test/rails_app/config/boot.rb +2 -2
- data/test/rails_app/config/database.yml +18 -0
- data/test/rails_app/config/initializers/devise.rb +71 -31
- data/test/rails_app/config/routes.rb +14 -6
- data/test/rails_app/config.ru +4 -0
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +21 -17
- data/test/rails_app/db/schema.rb +17 -51
- data/test/rails_app/lib/shared_admin.rb +9 -0
- data/test/rails_app/lib/shared_user.rb +23 -0
- data/test/rails_app/public/404.html +26 -0
- data/test/rails_app/public/422.html +26 -0
- data/test/rails_app/public/500.html +26 -0
- data/test/rails_app/public/favicon.ico +0 -0
- data/test/rails_app/script/rails +10 -0
- data/test/routes_test.rb +42 -9
- data/test/schema_test.rb +33 -0
- data/test/support/integration.rb +4 -4
- data/test/support/locale/en.yml +4 -0
- data/test/support/webrat/integrations/rails.rb +11 -19
- data/test/test_helper.rb +8 -2
- data/test/test_helpers_test.rb +64 -2
- metadata +106 -30
- data/TODO +0 -3
- data/lib/devise/encryptors/bcrypt.rb +0 -19
- data/lib/generators/devise_install_generator.rb +0 -4
- data/lib/generators/devise_views_generator.rb +0 -4
- 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 '
|
|
30
|
-
fill_in '
|
|
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
|
-
|
|
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
|
-
|
|
60
|
-
assert_have_selector
|
|
61
|
-
assert_contain '
|
|
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
|
-
|
|
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 '
|
|
108
|
+
fill_in 'Confirm new password', :with => 'other_password'
|
|
90
109
|
end
|
|
91
110
|
|
|
92
111
|
assert_response :success
|
|
93
|
-
|
|
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
|
-
|
|
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 '
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
78
|
-
token =
|
|
103
|
+
admin = create_admin_and_remember
|
|
104
|
+
token = admin.remember_token
|
|
79
105
|
|
|
80
|
-
|
|
81
|
-
|
|
106
|
+
admin.remember_created_at = old = 10.minutes.ago
|
|
107
|
+
admin.save!
|
|
82
108
|
|
|
83
|
-
get
|
|
84
|
-
assert (cookie_expires("
|
|
85
|
-
assert_equal token, signed_cookie("
|
|
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
|
-
|
|
92
|
-
token =
|
|
117
|
+
admin = create_admin_and_remember
|
|
118
|
+
token = admin.remember_token
|
|
93
119
|
|
|
94
|
-
|
|
95
|
-
|
|
120
|
+
admin.remember_created_at = old = 10.minutes.ago
|
|
121
|
+
admin.save!
|
|
96
122
|
|
|
97
|
-
get
|
|
98
|
-
assert (cookie_expires("
|
|
99
|
-
assert_not_equal token, signed_cookie("
|
|
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 '
|
|
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
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|