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
data/test/failure_app_test.rb
CHANGED
|
@@ -13,11 +13,11 @@ class FailureTest < ActiveSupport::TestCase
|
|
|
13
13
|
'REQUEST_METHOD' => 'GET',
|
|
14
14
|
'warden.options' => { :scope => :user },
|
|
15
15
|
'rack.session' => {},
|
|
16
|
-
'action_dispatch.request.formats' => Array(env_params.delete('formats') ||
|
|
16
|
+
'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
|
|
17
17
|
'rack.input' => "",
|
|
18
18
|
'warden' => OpenStruct.new(:message => nil)
|
|
19
19
|
}.merge!(env_params)
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
@response = Devise::FailureApp.call(env).to_a
|
|
22
22
|
@request = ActionDispatch::Request.new(env)
|
|
23
23
|
end
|
|
@@ -28,6 +28,11 @@ class FailureTest < ActiveSupport::TestCase
|
|
|
28
28
|
assert_equal 302, @response.first
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
test 'return 302 status for wildcard requests' do
|
|
32
|
+
call_failure 'action_dispatch.request.formats' => nil, 'HTTP_ACCEPT' => '*/*'
|
|
33
|
+
assert_equal 302, @response.first
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
test 'return to the default redirect location' do
|
|
32
37
|
call_failure
|
|
33
38
|
assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
|
|
@@ -64,6 +69,13 @@ class FailureTest < ActiveSupport::TestCase
|
|
|
64
69
|
assert_equal 302, @response.first
|
|
65
70
|
end
|
|
66
71
|
end
|
|
72
|
+
|
|
73
|
+
test 'redirects the correct format if it is a non-html format request' do
|
|
74
|
+
swap Devise, :navigational_formats => [:js] do
|
|
75
|
+
call_failure('formats' => :js)
|
|
76
|
+
assert_equal 'http://test.host/users/sign_in.js', @response.second["Location"]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
67
79
|
end
|
|
68
80
|
|
|
69
81
|
context 'For HTTP request' do
|
|
@@ -72,46 +84,76 @@ class FailureTest < ActiveSupport::TestCase
|
|
|
72
84
|
assert_equal 401, @response.first
|
|
73
85
|
end
|
|
74
86
|
|
|
75
|
-
test 'return
|
|
87
|
+
test 'return 401 status for unknown formats' do
|
|
88
|
+
call_failure 'formats' => []
|
|
89
|
+
assert_equal 401, @response.first
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
test 'return WWW-authenticate headers if model allows' do
|
|
76
93
|
call_failure('formats' => :xml)
|
|
77
94
|
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
|
|
78
95
|
end
|
|
79
96
|
|
|
80
|
-
test '
|
|
81
|
-
swap Devise, :
|
|
82
|
-
call_failure('formats' => :
|
|
83
|
-
|
|
84
|
-
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
|
|
85
|
-
assert_nil @response.second['WWW-Authenticate']
|
|
97
|
+
test 'does not return WWW-authenticate headers if model does not allow' do
|
|
98
|
+
swap Devise, :http_authenticatable => false do
|
|
99
|
+
call_failure('formats' => :xml)
|
|
100
|
+
assert_nil @response.second["WWW-Authenticate"]
|
|
86
101
|
end
|
|
87
102
|
end
|
|
88
103
|
|
|
89
|
-
test '
|
|
90
|
-
swap Devise, :
|
|
91
|
-
call_failure('formats' => :html
|
|
104
|
+
test 'works for any non navigational format' do
|
|
105
|
+
swap Devise, :navigational_formats => [] do
|
|
106
|
+
call_failure('formats' => :html)
|
|
92
107
|
assert_equal 401, @response.first
|
|
93
|
-
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
|
|
94
108
|
end
|
|
95
109
|
end
|
|
96
|
-
|
|
97
|
-
test 'uses the
|
|
110
|
+
|
|
111
|
+
test 'uses the failure message as response body' do
|
|
98
112
|
call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
|
|
99
113
|
assert_match '<error>Invalid email or password.</error>', @response.third.body
|
|
100
114
|
end
|
|
101
115
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
context 'on ajax call' do
|
|
117
|
+
context 'when http_authenticatable_on_xhr is false' do
|
|
118
|
+
test 'dont return 401 with navigational formats' do
|
|
119
|
+
swap Devise, :http_authenticatable_on_xhr => false do
|
|
120
|
+
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
|
121
|
+
assert_equal 302, @response.first
|
|
122
|
+
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
test 'dont return 401 with non navigational formats' do
|
|
127
|
+
swap Devise, :http_authenticatable_on_xhr => false do
|
|
128
|
+
call_failure('formats' => :json, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
|
129
|
+
assert_equal 302, @response.first
|
|
130
|
+
assert_equal 'http://test.host/users/sign_in.json', @response.second["Location"]
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context 'when http_authenticatable_on_xhr is true' do
|
|
136
|
+
test 'return 401' do
|
|
137
|
+
swap Devise, :http_authenticatable_on_xhr => true do
|
|
138
|
+
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
|
139
|
+
assert_equal 401, @response.first
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
test 'skip WWW-Authenticate header' do
|
|
144
|
+
swap Devise, :http_authenticatable_on_xhr => true do
|
|
145
|
+
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
|
146
|
+
assert_nil @response.second['WWW-Authenticate']
|
|
147
|
+
end
|
|
148
|
+
end
|
|
106
149
|
end
|
|
107
150
|
end
|
|
108
151
|
end
|
|
109
152
|
|
|
110
153
|
context 'With recall' do
|
|
111
|
-
test 'calls the original controller' do
|
|
154
|
+
test 'calls the original controller if invalid email or password' do
|
|
112
155
|
env = {
|
|
113
|
-
"
|
|
114
|
-
"warden.options" => { :recall => "new", :attempted_path => "/users/sign_in" },
|
|
156
|
+
"warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in" },
|
|
115
157
|
"devise.mapping" => Devise.mappings[:user],
|
|
116
158
|
"warden" => stub_everything
|
|
117
159
|
}
|
|
@@ -119,5 +161,27 @@ class FailureTest < ActiveSupport::TestCase
|
|
|
119
161
|
assert @response.third.body.include?('<h2>Sign in</h2>')
|
|
120
162
|
assert @response.third.body.include?('Invalid email or password.')
|
|
121
163
|
end
|
|
164
|
+
|
|
165
|
+
test 'calls the original controller if not confirmed email' do
|
|
166
|
+
env = {
|
|
167
|
+
"warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in", :message => :unconfirmed },
|
|
168
|
+
"devise.mapping" => Devise.mappings[:user],
|
|
169
|
+
"warden" => stub_everything
|
|
170
|
+
}
|
|
171
|
+
call_failure(env)
|
|
172
|
+
assert @response.third.body.include?('<h2>Sign in</h2>')
|
|
173
|
+
assert @response.third.body.include?('You have to confirm your account before continuing.')
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
test 'calls the original controller if inactive account' do
|
|
177
|
+
env = {
|
|
178
|
+
"warden.options" => { :recall => "devise/sessions#new", :attempted_path => "/users/sign_in", :message => :inactive },
|
|
179
|
+
"devise.mapping" => Devise.mappings[:user],
|
|
180
|
+
"warden" => stub_everything
|
|
181
|
+
}
|
|
182
|
+
call_failure(env)
|
|
183
|
+
assert @response.third.body.include?('<h2>Sign in</h2>')
|
|
184
|
+
assert @response.third.body.include?('Your account was not activated yet.')
|
|
185
|
+
end
|
|
122
186
|
end
|
|
123
187
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
if DEVISE_ORM == :active_record
|
|
4
|
+
require "generators/active_record/devise_generator"
|
|
5
|
+
|
|
6
|
+
class ActiveRecordGeneratorTest < Rails::Generators::TestCase
|
|
7
|
+
tests ActiveRecord::Generators::DeviseGenerator
|
|
8
|
+
destination File.expand_path("../../tmp", __FILE__)
|
|
9
|
+
setup :prepare_destination
|
|
10
|
+
|
|
11
|
+
test "all files are properly created" do
|
|
12
|
+
run_generator %w(monster)
|
|
13
|
+
assert_file "app/models/monster.rb", /devise/, /attr_accessible (:[a-z_]+(, )?)+/
|
|
14
|
+
assert_migration "db/migrate/devise_create_monsters.rb"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "all files are properly deleted" do
|
|
18
|
+
run_generator %w(monster)
|
|
19
|
+
run_generator %w(monster), :behavior => :revoke
|
|
20
|
+
assert_no_file "app/models/monster.rb"
|
|
21
|
+
assert_no_migration "db/migrate/devise_create_monsters.rb"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
require "generators/devise/devise_generator"
|
|
4
|
+
|
|
5
|
+
class DeviseGeneratorTest < Rails::Generators::TestCase
|
|
6
|
+
tests Devise::Generators::DeviseGenerator
|
|
7
|
+
destination File.expand_path("../../tmp", __FILE__)
|
|
8
|
+
|
|
9
|
+
setup do
|
|
10
|
+
prepare_destination
|
|
11
|
+
copy_routes
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
test "route generation for simple model names" do
|
|
15
|
+
run_generator %w(monster name:string)
|
|
16
|
+
assert_file "config/routes.rb", /devise_for :monsters/
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "route generation for namespaced model names" do
|
|
20
|
+
run_generator %w(monster/goblin name:string)
|
|
21
|
+
match = /devise_for :goblins, :class_name => "Monster::Goblin"/
|
|
22
|
+
assert_file "config/routes.rb", match
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def copy_routes
|
|
26
|
+
routes = File.expand_path("../../rails_app/config/routes.rb", __FILE__)
|
|
27
|
+
destination = File.join(destination_root, "config")
|
|
28
|
+
|
|
29
|
+
FileUtils.mkdir_p(destination)
|
|
30
|
+
FileUtils.cp routes, destination
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class InstallGeneratorTest < Rails::Generators::TestCase
|
|
4
|
+
tests Devise::Generators::InstallGenerator
|
|
5
|
+
destination File.expand_path("../../tmp", __FILE__)
|
|
6
|
+
setup :prepare_destination
|
|
7
|
+
|
|
8
|
+
test "Assert all files are properly created" do
|
|
9
|
+
run_generator
|
|
10
|
+
assert_file "config/initializers/devise.rb"
|
|
11
|
+
assert_file "config/locales/devise.en.yml"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
if DEVISE_ORM == :mongo_id
|
|
4
|
+
require "generators/mongo_id/devise_generator"
|
|
5
|
+
|
|
6
|
+
class MongoidGeneratorTest < Rails::Generators::TestCase
|
|
7
|
+
tests Mongoid::Generators::DeviseGenerator
|
|
8
|
+
destination File.expand_path("../../tmp", __FILE__)
|
|
9
|
+
setup :prepare_destination
|
|
10
|
+
|
|
11
|
+
test "all files are properly created" do
|
|
12
|
+
run_generator %w(monster)
|
|
13
|
+
assert_file "app/models/monster.rb", /devise/
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test "all files are properly deleted" do
|
|
17
|
+
run_generator %w(monster)
|
|
18
|
+
run_generator %w(monster), :behavior => :revoke
|
|
19
|
+
assert_no_file "app/models/monster.rb"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class ViewsGeneratorTest < Rails::Generators::TestCase
|
|
4
|
+
tests Devise::Generators::ViewsGenerator
|
|
5
|
+
destination File.expand_path("../../tmp", __FILE__)
|
|
6
|
+
setup :prepare_destination
|
|
7
|
+
|
|
8
|
+
test "Assert all views are properly created with no params" do
|
|
9
|
+
run_generator
|
|
10
|
+
assert_files
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
test "Assert all views are properly created with scope param param" do
|
|
14
|
+
run_generator %w(users)
|
|
15
|
+
assert_files "users"
|
|
16
|
+
|
|
17
|
+
run_generator %w(admins)
|
|
18
|
+
assert_files "admins"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def assert_files(scope = nil, template_engine = nil)
|
|
22
|
+
scope = "devise" if scope.nil?
|
|
23
|
+
assert_file "app/views/#{scope}/confirmations/new.html.erb"
|
|
24
|
+
assert_file "app/views/#{scope}/mailer/confirmation_instructions.html.erb"
|
|
25
|
+
assert_file "app/views/#{scope}/mailer/reset_password_instructions.html.erb"
|
|
26
|
+
assert_file "app/views/#{scope}/mailer/unlock_instructions.html.erb"
|
|
27
|
+
assert_file "app/views/#{scope}/passwords/edit.html.erb"
|
|
28
|
+
assert_file "app/views/#{scope}/passwords/new.html.erb"
|
|
29
|
+
assert_file "app/views/#{scope}/registrations/new.html.erb"
|
|
30
|
+
assert_file "app/views/#{scope}/registrations/edit.html.erb"
|
|
31
|
+
assert_file "app/views/#{scope}/sessions/new.html.erb"
|
|
32
|
+
assert_file "app/views/#{scope}/shared/_links.erb"
|
|
33
|
+
assert_file "app/views/#{scope}/unlocks/new.html.erb"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class IndifferentHashTest < ActiveSupport::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
@hash = Devise::IndifferentHash.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
test "it overwrites getter and setter" do
|
|
9
|
+
@hash[:foo] = "bar"
|
|
10
|
+
assert_equal "bar", @hash["foo"]
|
|
11
|
+
assert_equal "bar", @hash[:foo]
|
|
12
|
+
|
|
13
|
+
@hash["foo"] = "baz"
|
|
14
|
+
assert_equal "baz", @hash["foo"]
|
|
15
|
+
assert_equal "baz", @hash[:foo]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "it overwrites update" do
|
|
19
|
+
@hash.update :foo => "bar"
|
|
20
|
+
assert_equal "bar", @hash["foo"]
|
|
21
|
+
assert_equal "bar", @hash[:foo]
|
|
22
|
+
|
|
23
|
+
@hash.update "foo" => "baz"
|
|
24
|
+
assert_equal "baz", @hash["foo"]
|
|
25
|
+
assert_equal "baz", @hash[:foo]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "it returns a Hash on to_hash" do
|
|
29
|
+
@hash[:foo] = "bar"
|
|
30
|
+
assert_equal Hash["foo", "bar"], @hash.to_hash
|
|
31
|
+
assert_kind_of Hash, @hash.to_hash
|
|
32
|
+
end
|
|
33
|
+
end if defined?(Devise::IndifferentHash)
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
|
|
3
3
|
class AuthenticationSanityTest < ActionController::IntegrationTest
|
|
4
|
-
|
|
5
|
-
def setup
|
|
6
|
-
Devise.sign_out_all_scopes = false
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def teardown
|
|
10
|
-
Devise.sign_out_all_scopes = false
|
|
11
|
-
end
|
|
12
|
-
|
|
13
4
|
test 'home should be accessible without sign in' do
|
|
14
5
|
visit '/'
|
|
15
6
|
assert_response :success
|
|
@@ -18,14 +9,12 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
|
|
18
9
|
|
|
19
10
|
test 'sign in as user should not authenticate admin scope' do
|
|
20
11
|
sign_in_as_user
|
|
21
|
-
|
|
22
12
|
assert warden.authenticated?(:user)
|
|
23
13
|
assert_not warden.authenticated?(:admin)
|
|
24
14
|
end
|
|
25
15
|
|
|
26
16
|
test 'sign in as admin should not authenticate user scope' do
|
|
27
17
|
sign_in_as_admin
|
|
28
|
-
|
|
29
18
|
assert warden.authenticated?(:admin)
|
|
30
19
|
assert_not warden.authenticated?(:user)
|
|
31
20
|
end
|
|
@@ -33,59 +22,61 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
|
|
33
22
|
test 'sign in as both user and admin at same time' do
|
|
34
23
|
sign_in_as_user
|
|
35
24
|
sign_in_as_admin
|
|
36
|
-
|
|
37
25
|
assert warden.authenticated?(:user)
|
|
38
26
|
assert warden.authenticated?(:admin)
|
|
39
27
|
end
|
|
40
28
|
|
|
41
29
|
test 'sign out as user should not touch admin authentication if sign_out_all_scopes is false' do
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
swap Devise, :sign_out_all_scopes => false do
|
|
31
|
+
sign_in_as_user
|
|
32
|
+
sign_in_as_admin
|
|
33
|
+
get destroy_user_session_path
|
|
34
|
+
assert_not warden.authenticated?(:user)
|
|
35
|
+
assert warden.authenticated?(:admin)
|
|
36
|
+
end
|
|
48
37
|
end
|
|
49
38
|
|
|
50
39
|
test 'sign out as admin should not touch user authentication if sign_out_all_scopes is false' do
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
swap Devise, :sign_out_all_scopes => false do
|
|
41
|
+
sign_in_as_user
|
|
42
|
+
sign_in_as_admin
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
get destroy_admin_session_path
|
|
45
|
+
assert_not warden.authenticated?(:admin)
|
|
46
|
+
assert warden.authenticated?(:user)
|
|
47
|
+
end
|
|
57
48
|
end
|
|
58
49
|
|
|
59
50
|
test 'sign out as user should also sign out admin if sign_out_all_scopes is true' do
|
|
60
|
-
Devise
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
swap Devise, :sign_out_all_scopes => true do
|
|
52
|
+
sign_in_as_user
|
|
53
|
+
sign_in_as_admin
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
get destroy_user_session_path
|
|
56
|
+
assert_not warden.authenticated?(:user)
|
|
57
|
+
assert_not warden.authenticated?(:admin)
|
|
58
|
+
end
|
|
67
59
|
end
|
|
68
60
|
|
|
69
61
|
test 'sign out as admin should also sign out user if sign_out_all_scopes is true' do
|
|
70
|
-
Devise
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
swap Devise, :sign_out_all_scopes => true do
|
|
63
|
+
sign_in_as_user
|
|
64
|
+
sign_in_as_admin
|
|
73
65
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
66
|
+
get destroy_admin_session_path
|
|
67
|
+
assert_not warden.authenticated?(:admin)
|
|
68
|
+
assert_not warden.authenticated?(:user)
|
|
69
|
+
end
|
|
77
70
|
end
|
|
78
71
|
|
|
79
72
|
test 'not signed in as admin should not be able to access admins actions' do
|
|
80
73
|
get admins_path
|
|
81
|
-
|
|
82
74
|
assert_redirected_to new_admin_session_path
|
|
83
75
|
assert_not warden.authenticated?(:admin)
|
|
84
76
|
end
|
|
85
77
|
|
|
86
78
|
test 'not signed in as admin should not be able to access private route restricted to admins' do
|
|
87
79
|
get private_path
|
|
88
|
-
|
|
89
80
|
assert_redirected_to new_admin_session_path
|
|
90
81
|
assert_not warden.authenticated?(:admin)
|
|
91
82
|
end
|
|
@@ -94,7 +85,6 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
|
|
94
85
|
sign_in_as_user
|
|
95
86
|
assert warden.authenticated?(:user)
|
|
96
87
|
assert_not warden.authenticated?(:admin)
|
|
97
|
-
|
|
98
88
|
get private_path
|
|
99
89
|
assert_redirected_to new_admin_session_path
|
|
100
90
|
end
|
|
@@ -215,6 +205,13 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
|
|
|
215
205
|
assert_nil session[:"user_return_to"]
|
|
216
206
|
end
|
|
217
207
|
|
|
208
|
+
test 'sign in with xml format returns xml response' do
|
|
209
|
+
create_user
|
|
210
|
+
post user_session_path(:format => 'xml', :user => {:email => "user@test.com", :password => '123456'})
|
|
211
|
+
assert_response :success
|
|
212
|
+
assert_match /<\?xml version="1.0" encoding="UTF-8"\?>/, response.body
|
|
213
|
+
end
|
|
214
|
+
|
|
218
215
|
test 'redirect to configured home path for a given scope after sign in' do
|
|
219
216
|
sign_in_as_admin
|
|
220
217
|
assert_equal "/admin_area/home", @request.path
|
|
@@ -236,6 +233,36 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
|
|
|
236
233
|
get '/users'
|
|
237
234
|
assert_equal "Cart", @controller.user_session[:cart]
|
|
238
235
|
end
|
|
236
|
+
|
|
237
|
+
test 'does not explode when invalid user class is stored in session' do
|
|
238
|
+
klass = User
|
|
239
|
+
paths = ActiveSupport::Dependencies.autoload_paths.dup
|
|
240
|
+
|
|
241
|
+
begin
|
|
242
|
+
sign_in_as_user
|
|
243
|
+
assert warden.authenticated?(:user)
|
|
244
|
+
|
|
245
|
+
Object.send :remove_const, :User
|
|
246
|
+
ActiveSupport::Dependencies.autoload_paths.clear
|
|
247
|
+
|
|
248
|
+
visit "/users"
|
|
249
|
+
assert_not warden.authenticated?(:user)
|
|
250
|
+
ensure
|
|
251
|
+
Object.const_set(:User, klass)
|
|
252
|
+
ActiveSupport::Dependencies.autoload_paths.replace(paths)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
test 'session id is changed on sign in' do
|
|
257
|
+
get '/users'
|
|
258
|
+
session_id = request.session["session_id"]
|
|
259
|
+
|
|
260
|
+
get '/users'
|
|
261
|
+
assert_equal session_id, request.session["session_id"]
|
|
262
|
+
|
|
263
|
+
sign_in_as_user
|
|
264
|
+
assert_not_equal session_id, request.session["session_id"]
|
|
265
|
+
end
|
|
239
266
|
end
|
|
240
267
|
|
|
241
268
|
class AuthenticationWithScopesTest < ActionController::IntegrationTest
|
|
@@ -277,25 +304,13 @@ class AuthenticationWithScopesTest < ActionController::IntegrationTest
|
|
|
277
304
|
end
|
|
278
305
|
end
|
|
279
306
|
end
|
|
280
|
-
|
|
281
|
-
test 'uses the mapping from router' do
|
|
282
|
-
sign_in_as_user :visit => "/as/sign_in"
|
|
283
|
-
assert warden.authenticated?(:user)
|
|
284
|
-
assert_not warden.authenticated?(:admin)
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
test 'uses the mapping from nested devise_for call' do
|
|
288
|
-
sign_in_as_user :visit => "/devise_for/sign_in"
|
|
289
|
-
assert warden.authenticated?(:user)
|
|
290
|
-
assert_not warden.authenticated?(:admin)
|
|
291
|
-
end
|
|
292
307
|
end
|
|
293
308
|
|
|
294
309
|
class AuthenticationOthersTest < ActionController::IntegrationTest
|
|
295
310
|
test 'uses the custom controller with the custom controller view' do
|
|
296
311
|
get '/admin_area/sign_in'
|
|
297
312
|
assert_contain 'Sign in'
|
|
298
|
-
assert_contain 'Welcome to "sessions" controller!'
|
|
313
|
+
assert_contain 'Welcome to "admins/sessions" controller!'
|
|
299
314
|
assert_contain 'Welcome to "sessions/new" view!'
|
|
300
315
|
end
|
|
301
316
|
|
|
@@ -304,6 +319,11 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
|
|
304
319
|
assert_equal 404, response.status
|
|
305
320
|
end
|
|
306
321
|
|
|
322
|
+
test 'does not intercept Rails 401 responses' do
|
|
323
|
+
get '/unauthenticated'
|
|
324
|
+
assert_equal 401, response.status
|
|
325
|
+
end
|
|
326
|
+
|
|
307
327
|
test 'render 404 on roles without mapping' do
|
|
308
328
|
assert_raise AbstractController::ActionNotFound do
|
|
309
329
|
get '/sign_in'
|
|
@@ -317,28 +337,111 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
|
|
317
337
|
end
|
|
318
338
|
end
|
|
319
339
|
|
|
320
|
-
test 'registration in xml format' do
|
|
340
|
+
test 'registration in xml format works when recognizing path' do
|
|
321
341
|
assert_nothing_raised do
|
|
322
342
|
post user_registration_path(:format => 'xml', :user => {:email => "test@example.com", :password => "invalid"} )
|
|
323
343
|
end
|
|
324
344
|
end
|
|
325
345
|
|
|
326
|
-
test '
|
|
327
|
-
|
|
328
|
-
|
|
346
|
+
test 'uses the mapping from router' do
|
|
347
|
+
sign_in_as_user :visit => "/as/sign_in"
|
|
348
|
+
assert warden.authenticated?(:user)
|
|
349
|
+
assert_not warden.authenticated?(:admin)
|
|
350
|
+
end
|
|
329
351
|
|
|
330
|
-
|
|
352
|
+
test 'uses the mapping from nested devise_for call' do
|
|
353
|
+
sign_in_as_user :visit => "/devise_for/sign_in"
|
|
354
|
+
assert warden.authenticated?(:user)
|
|
355
|
+
assert_not warden.authenticated?(:admin)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
class AuthenticationRequestKeysTest < ActionController::IntegrationTest
|
|
360
|
+
test 'request keys are used on authentication' do
|
|
361
|
+
host! 'foo.bar.baz'
|
|
362
|
+
|
|
363
|
+
swap Devise, :request_keys => [:subdomain] do
|
|
364
|
+
User.expects(:find_for_authentication).with(:subdomain => 'foo', :email => 'user@test.com').returns(create_user)
|
|
331
365
|
sign_in_as_user
|
|
332
366
|
assert warden.authenticated?(:user)
|
|
367
|
+
end
|
|
368
|
+
end
|
|
333
369
|
|
|
334
|
-
|
|
335
|
-
|
|
370
|
+
test 'invalid request keys raises NoMethodError' do
|
|
371
|
+
swap Devise, :request_keys => [:unknown_method] do
|
|
372
|
+
assert_raise NoMethodError do
|
|
373
|
+
sign_in_as_user
|
|
374
|
+
end
|
|
336
375
|
|
|
337
|
-
visit "/users"
|
|
338
376
|
assert_not warden.authenticated?(:user)
|
|
339
|
-
ensure
|
|
340
|
-
Object.const_set(:User, klass)
|
|
341
|
-
ActiveSupport::Dependencies.autoload_paths.replace(paths)
|
|
342
377
|
end
|
|
343
378
|
end
|
|
379
|
+
|
|
380
|
+
test 'blank request keys cause authentication to abort' do
|
|
381
|
+
host! 'test.com'
|
|
382
|
+
|
|
383
|
+
swap Devise, :request_keys => [:subdomain] do
|
|
384
|
+
sign_in_as_user
|
|
385
|
+
assert_contain "Invalid email or password."
|
|
386
|
+
assert_not warden.authenticated?(:user)
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
test 'blank request keys cause authentication to abort unless if marked as not required' do
|
|
391
|
+
host! 'test.com'
|
|
392
|
+
|
|
393
|
+
swap Devise, :request_keys => { :subdomain => false } do
|
|
394
|
+
sign_in_as_user
|
|
395
|
+
assert warden.authenticated?(:user)
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
class AuthenticationSignOutViaTest < ActionController::IntegrationTest
|
|
401
|
+
def sign_in!(scope)
|
|
402
|
+
sign_in_as_admin(:visit => send("new_#{scope}_session_path"))
|
|
403
|
+
assert warden.authenticated?(scope)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
test 'allow sign out via delete when sign_out_via provides only delete' do
|
|
407
|
+
sign_in!(:sign_out_via_delete)
|
|
408
|
+
delete destroy_sign_out_via_delete_session_path
|
|
409
|
+
assert_not warden.authenticated?(:sign_out_via_delete)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
test 'do not allow sign out via get when sign_out_via provides only delete' do
|
|
413
|
+
sign_in!(:sign_out_via_delete)
|
|
414
|
+
get destroy_sign_out_via_delete_session_path
|
|
415
|
+
assert warden.authenticated?(:sign_out_via_delete)
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
test 'allow sign out via post when sign_out_via provides only post' do
|
|
419
|
+
sign_in!(:sign_out_via_post)
|
|
420
|
+
post destroy_sign_out_via_post_session_path
|
|
421
|
+
assert_not warden.authenticated?(:sign_out_via_post)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
test 'do not allow sign out via get when sign_out_via provides only post' do
|
|
425
|
+
sign_in!(:sign_out_via_post)
|
|
426
|
+
get destroy_sign_out_via_delete_session_path
|
|
427
|
+
assert warden.authenticated?(:sign_out_via_post)
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
test 'allow sign out via delete when sign_out_via provides delete and post' do
|
|
431
|
+
sign_in!(:sign_out_via_delete_or_post)
|
|
432
|
+
delete destroy_sign_out_via_delete_or_post_session_path
|
|
433
|
+
assert_not warden.authenticated?(:sign_out_via_delete_or_post)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
test 'allow sign out via post when sign_out_via provides delete and post' do
|
|
437
|
+
sign_in!(:sign_out_via_delete_or_post)
|
|
438
|
+
post destroy_sign_out_via_delete_or_post_session_path
|
|
439
|
+
assert_not warden.authenticated?(:sign_out_via_delete_or_post)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
test 'do not allow sign out via get when sign_out_via provides delete and post' do
|
|
443
|
+
sign_in!(:sign_out_via_delete_or_post)
|
|
444
|
+
get destroy_sign_out_via_delete_or_post_session_path
|
|
445
|
+
assert warden.authenticated?(:sign_out_via_delete_or_post)
|
|
446
|
+
end
|
|
344
447
|
end
|