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
|
@@ -7,12 +7,23 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|
|
7
7
|
sign_in_as_new_user_with_token
|
|
8
8
|
|
|
9
9
|
assert_response :success
|
|
10
|
-
|
|
10
|
+
assert_current_url "/users?secret_token=#{VALID_AUTHENTICATION_TOKEN}"
|
|
11
11
|
assert_contain 'Welcome'
|
|
12
12
|
assert warden.authenticated?(:user)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
test 'authenticate with valid authentication token key but does not store if stateless' do
|
|
17
|
+
swap Devise, :token_authentication_key => :secret_token, :stateless_token => true do
|
|
18
|
+
sign_in_as_new_user_with_token
|
|
19
|
+
assert warden.authenticated?(:user)
|
|
20
|
+
|
|
21
|
+
get users_path
|
|
22
|
+
assert_redirected_to new_user_session_path
|
|
23
|
+
assert_not warden.authenticated?(:user)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
16
27
|
test 'authenticate with valid authentication token key and value through http' do
|
|
17
28
|
swap Devise, :token_authentication_key => :secret_token do
|
|
18
29
|
sign_in_as_new_user_with_token(:http_auth => true)
|
|
@@ -65,15 +76,42 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|
|
65
76
|
end
|
|
66
77
|
end
|
|
67
78
|
|
|
79
|
+
test 'authenticate with valid authentication token key and do not store if stateless and timeoutable are enabled' do
|
|
80
|
+
swap Devise, :token_authentication_key => :secret_token, :stateless_token => true, :timeout_in => (0.1).second do
|
|
81
|
+
user = sign_in_as_new_user_with_token
|
|
82
|
+
assert warden.authenticated?(:user)
|
|
83
|
+
|
|
84
|
+
# Expiring does not work because we are setting the session value when accessing it
|
|
85
|
+
sleep 0.3
|
|
86
|
+
|
|
87
|
+
get_users_path_as_existing_user(user)
|
|
88
|
+
assert warden.authenticated?(:user)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
test 'should not be subject to injection' do
|
|
93
|
+
swap Devise, :token_authentication_key => :secret_token do
|
|
94
|
+
user1 = create_user_with_authentication_token()
|
|
95
|
+
|
|
96
|
+
# Clean up user cache
|
|
97
|
+
@user = nil
|
|
98
|
+
|
|
99
|
+
user2 = create_user_with_authentication_token(:email => "another@test.com")
|
|
100
|
+
user2.update_attribute(:authentication_token, "ANOTHERTOKEN")
|
|
101
|
+
|
|
102
|
+
assert_not_equal user1, user2
|
|
103
|
+
visit users_path(Devise.token_authentication_key.to_s + '[$ne]' => user1.authentication_token)
|
|
104
|
+
assert_nil warden.user(:user)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
68
108
|
private
|
|
69
109
|
|
|
70
110
|
def sign_in_as_new_user_with_token(options = {})
|
|
71
|
-
options
|
|
72
|
-
options[:auth_token] ||= VALID_AUTHENTICATION_TOKEN
|
|
111
|
+
user = options.delete(:user) || create_user_with_authentication_token(options)
|
|
73
112
|
|
|
74
|
-
|
|
75
|
-
user.authentication_token
|
|
76
|
-
user.save
|
|
113
|
+
options[:auth_token_key] ||= Devise.token_authentication_key
|
|
114
|
+
options[:auth_token] ||= user.authentication_token
|
|
77
115
|
|
|
78
116
|
if options[:http_auth]
|
|
79
117
|
header = "Basic #{ActiveSupport::Base64.encode64("#{VALID_AUTHENTICATION_TOKEN}:X")}"
|
|
@@ -85,4 +123,15 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|
|
85
123
|
user
|
|
86
124
|
end
|
|
87
125
|
|
|
126
|
+
def create_user_with_authentication_token(options={})
|
|
127
|
+
user = create_user(options)
|
|
128
|
+
user.authentication_token = VALID_AUTHENTICATION_TOKEN
|
|
129
|
+
user.save
|
|
130
|
+
user
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def get_users_path_as_existing_user(user)
|
|
134
|
+
sign_in_as_new_user_with_token(:user => user)
|
|
135
|
+
end
|
|
136
|
+
|
|
88
137
|
end
|
|
@@ -35,6 +35,10 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
|
|
|
35
35
|
assert_equal ['test@example.com'], mail.from
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
test 'setup reply to as copy from sender' do
|
|
39
|
+
assert_equal ['test@example.com'], mail.reply_to
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
test 'setup subject from I18n' do
|
|
39
43
|
store_translations :en, :devise => { :mailer => { :confirmation_instructions => { :subject => 'Account Confirmation' } } } do
|
|
40
44
|
assert_equal 'Account Confirmation', mail.subject
|
|
@@ -38,6 +38,10 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
|
|
|
38
38
|
assert_equal ['test@example.com'], mail.from
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
test 'setup reply to as copy from sender' do
|
|
42
|
+
assert_equal ['test@example.com'], mail.reply_to
|
|
43
|
+
end
|
|
44
|
+
|
|
41
45
|
test 'setup subject from I18n' do
|
|
42
46
|
store_translations :en, :devise => { :mailer => { :reset_password_instructions => { :subject => 'Reset instructions' } } } do
|
|
43
47
|
assert_equal 'Reset instructions', mail.subject
|
|
@@ -38,6 +38,10 @@ class UnlockInstructionsTest < ActionMailer::TestCase
|
|
|
38
38
|
assert_equal ['test@example.com'], mail.from
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
test 'setup reply to as copy from sender' do
|
|
42
|
+
assert_equal ['test@example.com'], mail.reply_to
|
|
43
|
+
end
|
|
44
|
+
|
|
41
45
|
test 'setup subject from I18n' do
|
|
42
46
|
store_translations :en, :devise => { :mailer => { :unlock_instructions => { :subject => 'Yo unlock instructions' } } } do
|
|
43
47
|
assert_equal 'Yo unlock instructions', mail.subject
|
data/test/mapping_test.rb
CHANGED
|
@@ -12,22 +12,42 @@ class MappingTest < ActiveSupport::TestCase
|
|
|
12
12
|
mapping = Devise.mappings[:user]
|
|
13
13
|
assert_equal User, mapping.to
|
|
14
14
|
assert_equal User.devise_modules, mapping.modules
|
|
15
|
-
assert_equal
|
|
15
|
+
assert_equal "users", mapping.scoped_path
|
|
16
16
|
assert_equal :user, mapping.singular
|
|
17
17
|
assert_equal "users", mapping.path
|
|
18
|
+
assert_equal "/users", mapping.fullpath
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'store options with namespace' do
|
|
22
|
+
mapping = Devise.mappings[:publisher_account]
|
|
23
|
+
assert_equal Admin, mapping.to
|
|
24
|
+
assert_equal "publisher/accounts", mapping.scoped_path
|
|
25
|
+
assert_equal :publisher_account, mapping.singular
|
|
26
|
+
assert_equal "accounts", mapping.path
|
|
27
|
+
assert_equal "/publisher/accounts", mapping.fullpath
|
|
18
28
|
end
|
|
19
29
|
|
|
20
30
|
test 'allows path to be given' do
|
|
21
31
|
assert_equal "admin_area", Devise.mappings[:admin].path
|
|
22
32
|
end
|
|
23
33
|
|
|
34
|
+
test 'sign_out_via defaults to :get' do
|
|
35
|
+
assert_equal :get, Devise.mappings[:user].sign_out_via
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'allows custom sign_out_via to be given' do
|
|
39
|
+
assert_equal :delete, Devise.mappings[:sign_out_via_delete].sign_out_via
|
|
40
|
+
assert_equal :post, Devise.mappings[:sign_out_via_post].sign_out_via
|
|
41
|
+
assert_equal [:delete, :post], Devise.mappings[:sign_out_via_delete_or_post].sign_out_via
|
|
42
|
+
end
|
|
43
|
+
|
|
24
44
|
test 'allows custom singular to be given' do
|
|
25
45
|
assert_equal "accounts", Devise.mappings[:manager].path
|
|
26
46
|
end
|
|
27
47
|
|
|
28
48
|
test 'has strategies depending on the model declaration' do
|
|
29
49
|
assert_equal [:rememberable, :token_authenticatable, :database_authenticatable], Devise.mappings[:user].strategies
|
|
30
|
-
assert_equal [:database_authenticatable], Devise.mappings[:admin].strategies
|
|
50
|
+
assert_equal [:rememberable, :database_authenticatable], Devise.mappings[:admin].strategies
|
|
31
51
|
end
|
|
32
52
|
|
|
33
53
|
test 'find scope for a given object' do
|
|
@@ -80,6 +100,20 @@ class MappingTest < ActiveSupport::TestCase
|
|
|
80
100
|
assert mapping.recoverable?
|
|
81
101
|
assert mapping.lockable?
|
|
82
102
|
assert_not mapping.confirmable?
|
|
83
|
-
assert_not mapping.
|
|
103
|
+
assert_not mapping.omniauthable?
|
|
84
104
|
end
|
|
105
|
+
|
|
106
|
+
test 'find mapping by path' do
|
|
107
|
+
assert_raise RuntimeError do
|
|
108
|
+
Devise::Mapping.find_by_path!('/accounts/facebook/callback')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
assert_nothing_raised do
|
|
112
|
+
Devise::Mapping.find_by_path!('/:locale/accounts/login')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
assert_nothing_raised do
|
|
116
|
+
Devise::Mapping.find_by_path!('/accounts/facebook/callback', :path)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
85
119
|
end
|
|
@@ -48,10 +48,10 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
|
48
48
|
assert_blank user.errors[:email]
|
|
49
49
|
|
|
50
50
|
assert_not user.confirm!
|
|
51
|
-
assert_equal "was already confirmed", user.errors[:email].join
|
|
51
|
+
assert_equal "was already confirmed, please try signing in", user.errors[:email].join
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
test 'should find and confirm
|
|
54
|
+
test 'should find and confirm a user automatically' do
|
|
55
55
|
user = create_user
|
|
56
56
|
confirmed_user = User.confirm_by_token(user.confirmation_token)
|
|
57
57
|
assert_equal confirmed_user, user
|
|
@@ -76,7 +76,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
|
76
76
|
user.save
|
|
77
77
|
confirmed_user = User.confirm_by_token(user.confirmation_token)
|
|
78
78
|
assert confirmed_user.confirmed?
|
|
79
|
-
assert_equal "was already confirmed", confirmed_user.errors[:email].join
|
|
79
|
+
assert_equal "was already confirmed, please try signing in", confirmed_user.errors[:email].join
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
test 'should send confirmation instructions by email' do
|
|
@@ -127,7 +127,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
|
127
127
|
User.send_confirmation_instructions(:email => user.email)
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
test 'should always have confirmation token when email is sent' do
|
|
132
132
|
user = new_user
|
|
133
133
|
user.instance_eval { def confirmation_required?; false end }
|
|
@@ -160,17 +160,17 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
|
160
160
|
user.confirm!
|
|
161
161
|
assert_not user.resend_confirmation_token
|
|
162
162
|
assert user.confirmed?
|
|
163
|
-
assert_equal 'was already confirmed', user.errors[:email].join
|
|
163
|
+
assert_equal 'was already confirmed, please try signing in', user.errors[:email].join
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
test 'confirm time should fallback to devise confirm in default configuration' do
|
|
167
167
|
swap Devise, :confirm_within => 1.day do
|
|
168
168
|
user = new_user
|
|
169
169
|
user.confirmation_sent_at = 2.days.ago
|
|
170
|
-
assert_not user.
|
|
170
|
+
assert_not user.active_for_authentication?
|
|
171
171
|
|
|
172
172
|
Devise.confirm_within = 3.days
|
|
173
|
-
assert user.
|
|
173
|
+
assert user.active_for_authentication?
|
|
174
174
|
end
|
|
175
175
|
end
|
|
176
176
|
|
|
@@ -180,42 +180,59 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
|
180
180
|
user = create_user
|
|
181
181
|
|
|
182
182
|
user.confirmation_sent_at = 4.days.ago
|
|
183
|
-
assert user.
|
|
183
|
+
assert user.active_for_authentication?
|
|
184
184
|
|
|
185
185
|
user.confirmation_sent_at = 5.days.ago
|
|
186
|
-
assert_not user.
|
|
186
|
+
assert_not user.active_for_authentication?
|
|
187
187
|
end
|
|
188
188
|
end
|
|
189
189
|
|
|
190
190
|
test 'should be active when already confirmed' do
|
|
191
191
|
user = create_user
|
|
192
192
|
assert_not user.confirmed?
|
|
193
|
-
assert_not user.
|
|
193
|
+
assert_not user.active_for_authentication?
|
|
194
194
|
|
|
195
195
|
user.confirm!
|
|
196
196
|
assert user.confirmed?
|
|
197
|
-
assert user.
|
|
197
|
+
assert user.active_for_authentication?
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
test 'should not be active when confirm in is zero' do
|
|
201
201
|
Devise.confirm_within = 0.days
|
|
202
202
|
user = create_user
|
|
203
203
|
user.confirmation_sent_at = Date.today
|
|
204
|
-
assert_not user.
|
|
204
|
+
assert_not user.active_for_authentication?
|
|
205
205
|
end
|
|
206
206
|
|
|
207
207
|
test 'should not be active without confirmation' do
|
|
208
208
|
user = create_user
|
|
209
209
|
user.confirmation_sent_at = nil
|
|
210
210
|
user.save
|
|
211
|
-
assert_not user.reload.
|
|
211
|
+
assert_not user.reload.active_for_authentication?
|
|
212
212
|
end
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
test 'should be active without confirmation when confirmation is not required' do
|
|
215
215
|
user = create_user
|
|
216
216
|
user.instance_eval { def confirmation_required?; false end }
|
|
217
217
|
user.confirmation_sent_at = nil
|
|
218
218
|
user.save
|
|
219
|
-
assert user.reload.
|
|
219
|
+
assert user.reload.active_for_authentication?
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
test 'should find a user to send email instructions for the user confirm it\'s email by authentication_keys' do
|
|
223
|
+
swap Devise, :authentication_keys => [:username, :email] do
|
|
224
|
+
user = create_user
|
|
225
|
+
confirm_user = User.send_confirmation_instructions(:email => user.email, :username => user.username)
|
|
226
|
+
assert_equal confirm_user, user
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
test 'should require all confirmation_keys' do
|
|
231
|
+
swap Devise, :confirmation_keys => [:username, :email] do
|
|
232
|
+
user = create_user
|
|
233
|
+
confirm_user = User.send_confirmation_instructions(:email => user.email)
|
|
234
|
+
assert_not confirm_user.persisted?
|
|
235
|
+
assert_equal "can't be blank", confirm_user.errors[:username].join
|
|
236
|
+
end
|
|
220
237
|
end
|
|
221
238
|
end
|
|
@@ -2,53 +2,31 @@ require 'test_helper'
|
|
|
2
2
|
require 'digest/sha1'
|
|
3
3
|
|
|
4
4
|
class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
swap klass, options.merge(:encryptor => encryptor) do
|
|
14
|
-
begin
|
|
15
|
-
yield
|
|
16
|
-
ensure
|
|
17
|
-
klass.instance_variable_set(:@encryptor_class, nil)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
5
|
+
test 'should downcase case insensitive keys when saving' do
|
|
6
|
+
# case_insensitive_keys is set to :email by default.
|
|
7
|
+
email = 'Foo@Bar.com'
|
|
8
|
+
user = new_user(:email => email)
|
|
9
|
+
|
|
10
|
+
assert_equal email, user.email
|
|
11
|
+
user.save!
|
|
12
|
+
assert_equal email.downcase, user.email
|
|
20
13
|
end
|
|
21
|
-
|
|
14
|
+
|
|
22
15
|
test 'should respond to password and password confirmation' do
|
|
23
16
|
user = new_user
|
|
24
17
|
assert user.respond_to?(:password)
|
|
25
18
|
assert user.respond_to?(:password_confirmation)
|
|
26
19
|
end
|
|
27
20
|
|
|
28
|
-
test 'should generate encrypted password
|
|
21
|
+
test 'should generate encrypted password while setting password' do
|
|
29
22
|
user = new_user
|
|
30
|
-
assert_present user.password_salt
|
|
31
23
|
assert_present user.encrypted_password
|
|
32
24
|
end
|
|
33
25
|
|
|
34
|
-
test '
|
|
35
|
-
user =
|
|
36
|
-
|
|
37
|
-
user.
|
|
38
|
-
user.save!
|
|
39
|
-
assert_equal salt, user.password_salt
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
test 'should generate a base64 hash using SecureRandom for password salt' do
|
|
43
|
-
swap_with_encryptor User, :sha1 do
|
|
44
|
-
ActiveSupport::SecureRandom.expects(:base64).with(15).returns('friendly_token')
|
|
45
|
-
assert_equal 'friendly_token', new_user.password_salt
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
test 'should not generate salt if password is blank' do
|
|
50
|
-
assert_blank new_user(:password => nil).password_salt
|
|
51
|
-
assert_blank new_user(:password => '').password_salt
|
|
26
|
+
test 'allow authenticatable_salt to work even with nil encrypted password' do
|
|
27
|
+
user = User.new
|
|
28
|
+
user.encrypted_password = nil
|
|
29
|
+
assert_nil user.authenticatable_salt
|
|
52
30
|
end
|
|
53
31
|
|
|
54
32
|
test 'should not generate encrypted password if password is blank' do
|
|
@@ -64,47 +42,12 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
|
|
64
42
|
assert_not_equal encrypted_password, user.encrypted_password
|
|
65
43
|
end
|
|
66
44
|
|
|
67
|
-
test 'should fallback to sha1 as default encryption' do
|
|
68
|
-
user = new_user
|
|
69
|
-
assert_equal encrypt_password(user), user.encrypted_password
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
test 'should fallback to devise pepper default configuration' do
|
|
73
|
-
begin
|
|
74
|
-
Devise.pepper = ''
|
|
75
|
-
user = new_user
|
|
76
|
-
assert_equal encrypt_password(user), user.encrypted_password
|
|
77
|
-
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
|
78
|
-
|
|
79
|
-
Devise.pepper = 'new_pepper'
|
|
80
|
-
user = new_user
|
|
81
|
-
assert_equal encrypt_password(user, 'new_pepper'), user.encrypted_password
|
|
82
|
-
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
|
83
|
-
ensure
|
|
84
|
-
Devise.pepper = nil
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
test 'should respect encryptor configuration' do
|
|
89
|
-
swap_with_encryptor User, :sha512 do
|
|
90
|
-
user = create_user
|
|
91
|
-
assert_equal user.encrypted_password, encrypt_password(user, User.pepper, User.stretches, ::Devise::Encryptors::Sha512)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
45
|
test 'should test for a valid password' do
|
|
96
46
|
user = create_user
|
|
97
47
|
assert user.valid_password?('123456')
|
|
98
48
|
assert_not user.valid_password?('654321')
|
|
99
49
|
end
|
|
100
50
|
|
|
101
|
-
test 'should not validate password when salt is nil' do
|
|
102
|
-
admin = create_admin
|
|
103
|
-
admin.password_salt = nil
|
|
104
|
-
admin.save
|
|
105
|
-
assert_not admin.valid_password?('123456')
|
|
106
|
-
end
|
|
107
|
-
|
|
108
51
|
test 'should respond to current password' do
|
|
109
52
|
assert new_user.respond_to?(:current_password)
|
|
110
53
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class EncryptableTest < ActiveSupport::TestCase
|
|
4
|
+
def encrypt_password(admin, pepper=Admin.pepper, stretches=Admin.stretches, encryptor=Admin.encryptor_class)
|
|
5
|
+
encryptor.digest('123456', stretches, admin.password_salt, pepper)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def swap_with_encryptor(klass, encryptor, options={})
|
|
9
|
+
klass.instance_variable_set(:@encryptor_class, nil)
|
|
10
|
+
|
|
11
|
+
swap klass, options.merge(:encryptor => encryptor) do
|
|
12
|
+
begin
|
|
13
|
+
yield
|
|
14
|
+
ensure
|
|
15
|
+
klass.instance_variable_set(:@encryptor_class, nil)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test 'should generate salt while setting password' do
|
|
21
|
+
assert_present create_admin.password_salt
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'should not change password salt when updating' do
|
|
25
|
+
admin = create_admin
|
|
26
|
+
salt = admin.password_salt
|
|
27
|
+
admin.expects(:password_salt=).never
|
|
28
|
+
admin.save!
|
|
29
|
+
assert_equal salt, admin.password_salt
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test 'should generate a base64 hash using SecureRandom for password salt' do
|
|
33
|
+
swap_with_encryptor Admin, :sha1 do
|
|
34
|
+
ActiveSupport::SecureRandom.expects(:base64).with(15).returns('friendly_token')
|
|
35
|
+
assert_equal 'friendly_token', create_admin.password_salt
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test 'should not generate salt if password is blank' do
|
|
40
|
+
assert_blank create_admin(:password => nil).password_salt
|
|
41
|
+
assert_blank create_admin(:password => '').password_salt
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test 'should encrypt password again if password has changed' do
|
|
45
|
+
admin = create_admin
|
|
46
|
+
encrypted_password = admin.encrypted_password
|
|
47
|
+
admin.password = admin.password_confirmation = 'new_password'
|
|
48
|
+
admin.save!
|
|
49
|
+
assert_not_equal encrypted_password, admin.encrypted_password
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test 'should respect encryptor configuration' do
|
|
53
|
+
swap_with_encryptor Admin, :sha512 do
|
|
54
|
+
admin = create_admin
|
|
55
|
+
assert_equal admin.encrypted_password, encrypt_password(admin, Admin.pepper, Admin.stretches, ::Devise::Encryptors::Sha512)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test 'should not validate password when salt is nil' do
|
|
60
|
+
admin = create_admin
|
|
61
|
+
admin.password_salt = nil
|
|
62
|
+
admin.save
|
|
63
|
+
assert_not admin.valid_password?('123456')
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -47,15 +47,15 @@ class LockableTest < ActiveSupport::TestCase
|
|
|
47
47
|
assert user.access_locked?
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
test "
|
|
50
|
+
test "active_for_authentication? should be the opposite of locked?" do
|
|
51
51
|
user = create_user
|
|
52
52
|
user.confirm!
|
|
53
|
-
assert user.
|
|
53
|
+
assert user.active_for_authentication?
|
|
54
54
|
user.lock_access!
|
|
55
|
-
assert_not user.
|
|
55
|
+
assert_not user.active_for_authentication?
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
test "should unlock
|
|
58
|
+
test "should unlock a user by cleaning locked_at, falied_attempts and unlock_token" do
|
|
59
59
|
user = create_user
|
|
60
60
|
user.lock_access!
|
|
61
61
|
assert_not_nil user.reload.locked_at
|
|
@@ -67,12 +67,6 @@ class LockableTest < ActiveSupport::TestCase
|
|
|
67
67
|
assert_equal 0, user.reload.failed_attempts
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
test 'should not unlock an unlocked user' do
|
|
71
|
-
user = create_user
|
|
72
|
-
assert_not user.unlock_access!
|
|
73
|
-
assert_match "was not locked", user.errors[:email].join
|
|
74
|
-
end
|
|
75
|
-
|
|
76
70
|
test "new user should not be locked and should have zero failed_attempts" do
|
|
77
71
|
assert_not new_user.access_locked?
|
|
78
72
|
assert_equal 0, create_user.failed_attempts
|
|
@@ -141,7 +135,7 @@ class LockableTest < ActiveSupport::TestCase
|
|
|
141
135
|
end
|
|
142
136
|
end
|
|
143
137
|
|
|
144
|
-
test 'should find and unlock
|
|
138
|
+
test 'should find and unlock a user automatically' do
|
|
145
139
|
user = create_user
|
|
146
140
|
user.lock_access!
|
|
147
141
|
locked_user = User.unlock_access_by_token(user.unlock_token)
|
|
@@ -178,6 +172,23 @@ class LockableTest < ActiveSupport::TestCase
|
|
|
178
172
|
assert_equal 'not found', unlock_user.errors[:email].join
|
|
179
173
|
end
|
|
180
174
|
|
|
175
|
+
test 'should find a user to send unlock instructions by authentication_keys' do
|
|
176
|
+
swap Devise, :authentication_keys => [:username, :email] do
|
|
177
|
+
user = create_user
|
|
178
|
+
unlock_user = User.send_unlock_instructions(:email => user.email, :username => user.username)
|
|
179
|
+
assert_equal unlock_user, user
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
test 'should require all unlock_keys' do
|
|
184
|
+
swap Devise, :unlock_keys => [:username, :email] do
|
|
185
|
+
user = create_user
|
|
186
|
+
unlock_user = User.send_unlock_instructions(:email => user.email)
|
|
187
|
+
assert_not unlock_user.persisted?
|
|
188
|
+
assert_equal "can't be blank", unlock_user.errors[:username].join
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
181
192
|
test 'should not be able to send instructions if the user is not locked' do
|
|
182
193
|
user = create_user
|
|
183
194
|
assert_not user.resend_unlock_token
|
|
@@ -185,4 +196,30 @@ class LockableTest < ActiveSupport::TestCase
|
|
|
185
196
|
assert_equal 'was not locked', user.errors[:email].join
|
|
186
197
|
end
|
|
187
198
|
|
|
199
|
+
test 'should unlock account if lock has expired and increase attempts on failure' do
|
|
200
|
+
swap Devise, :unlock_in => 1.minute do
|
|
201
|
+
user = create_user
|
|
202
|
+
user.confirm!
|
|
203
|
+
|
|
204
|
+
user.failed_attempts = 2
|
|
205
|
+
user.locked_at = 2.minutes.ago
|
|
206
|
+
|
|
207
|
+
user.valid_for_authentication? { false }
|
|
208
|
+
assert_equal 1, user.failed_attempts
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
test 'should unlock account if lock has expired on success' do
|
|
213
|
+
swap Devise, :unlock_in => 1.minute do
|
|
214
|
+
user = create_user
|
|
215
|
+
user.confirm!
|
|
216
|
+
|
|
217
|
+
user.failed_attempts = 2
|
|
218
|
+
user.locked_at = 2.minutes.ago
|
|
219
|
+
|
|
220
|
+
user.valid_for_authentication? { true }
|
|
221
|
+
assert_equal 0, user.failed_attempts
|
|
222
|
+
assert_nil user.locked_at
|
|
223
|
+
end
|
|
224
|
+
end
|
|
188
225
|
end
|
|
@@ -86,6 +86,23 @@ class RecoverableTest < ActiveSupport::TestCase
|
|
|
86
86
|
assert_equal "not found", reset_password_user.errors[:email].join
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
test 'should find a user to send instructions by authentication_keys' do
|
|
90
|
+
swap Devise, :authentication_keys => [:username, :email] do
|
|
91
|
+
user = create_user
|
|
92
|
+
reset_password_user = User.send_reset_password_instructions(:email => user.email, :username => user.username)
|
|
93
|
+
assert_equal reset_password_user, user
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
test 'should require all reset_password_keys' do
|
|
98
|
+
swap Devise, :reset_password_keys => [:username, :email] do
|
|
99
|
+
user = create_user
|
|
100
|
+
reset_password_user = User.send_reset_password_instructions(:email => user.email)
|
|
101
|
+
assert_not reset_password_user.persisted?
|
|
102
|
+
assert_equal "can't be blank", reset_password_user.errors[:username].join
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
89
106
|
test 'should reset reset_password_token before send the reset instructions email' do
|
|
90
107
|
user = create_user
|
|
91
108
|
token = user.reset_password_token
|
|
@@ -108,18 +125,27 @@ class RecoverableTest < ActiveSupport::TestCase
|
|
|
108
125
|
assert_equal reset_password_user, user
|
|
109
126
|
end
|
|
110
127
|
|
|
111
|
-
test 'should a new record with errors if no reset_password_token is found' do
|
|
128
|
+
test 'should return a new record with errors if no reset_password_token is found' do
|
|
112
129
|
reset_password_user = User.reset_password_by_token(:reset_password_token => 'invalid_token')
|
|
113
130
|
assert_not reset_password_user.persisted?
|
|
114
131
|
assert_equal "is invalid", reset_password_user.errors[:reset_password_token].join
|
|
115
132
|
end
|
|
116
133
|
|
|
117
|
-
test 'should a new record with errors if reset_password_token is blank' do
|
|
134
|
+
test 'should return a new record with errors if reset_password_token is blank' do
|
|
118
135
|
reset_password_user = User.reset_password_by_token(:reset_password_token => '')
|
|
119
136
|
assert_not reset_password_user.persisted?
|
|
120
137
|
assert_match "can't be blank", reset_password_user.errors[:reset_password_token].join
|
|
121
138
|
end
|
|
122
139
|
|
|
140
|
+
test 'should return a new record with errors if password is blank' do
|
|
141
|
+
user = create_user
|
|
142
|
+
user.send :generate_reset_password_token!
|
|
143
|
+
|
|
144
|
+
reset_password_user = User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '')
|
|
145
|
+
assert_not reset_password_user.errors.empty?
|
|
146
|
+
assert_match "can't be blank", reset_password_user.errors[:password].join
|
|
147
|
+
end
|
|
148
|
+
|
|
123
149
|
test 'should reset successfully user password given the new password and confirmation' do
|
|
124
150
|
user = create_user
|
|
125
151
|
old_password = user.password
|