clearance 1.17.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of clearance might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +8 -14
- data/Appraisals +11 -3
- data/Gemfile +3 -6
- data/Gemfile.lock +91 -87
- data/NEWS.md +233 -15
- data/README.md +54 -28
- data/app/controllers/clearance/base_controller.rb +8 -1
- data/app/controllers/clearance/passwords_controller.rb +35 -45
- data/app/controllers/clearance/sessions_controller.rb +3 -18
- data/app/controllers/clearance/users_controller.rb +2 -17
- data/clearance.gemspec +15 -9
- data/config/locales/clearance.en.yml +1 -0
- data/config/routes.rb +1 -1
- data/gemfiles/rails_5.0.gemfile +5 -6
- data/gemfiles/rails_5.1.gemfile +5 -6
- data/gemfiles/rails_5.2.gemfile +5 -6
- data/gemfiles/{rails_4.2.gemfile → rails_6.0.gemfile} +7 -7
- data/lib/clearance.rb +0 -8
- data/lib/clearance/authentication.rb +1 -9
- data/lib/clearance/authorization.rb +2 -11
- data/lib/clearance/back_door.rb +1 -1
- data/lib/clearance/configuration.rb +30 -19
- data/lib/clearance/password_strategies.rb +5 -4
- data/lib/clearance/password_strategies/argon2.rb +23 -0
- data/lib/clearance/password_strategies/bcrypt.rb +17 -11
- data/lib/clearance/rack_session.rb +5 -1
- data/lib/clearance/session.rb +40 -12
- data/lib/clearance/testing/deny_access_matcher.rb +10 -20
- data/lib/clearance/user.rb +3 -24
- data/lib/clearance/version.rb +1 -1
- data/lib/generators/clearance/install/install_generator.rb +12 -12
- data/lib/generators/clearance/install/templates/README +10 -4
- data/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb.erb +1 -1
- data/lib/generators/clearance/install/templates/db/migrate/create_users.rb.erb +1 -1
- data/lib/generators/clearance/routes/templates/routes.rb +1 -1
- data/spec/acceptance/clearance_installation_spec.rb +0 -4
- data/spec/app_templates/app/models/user.rb +1 -1
- data/spec/app_templates/testapp/app/controllers/home_controller.rb +1 -5
- data/spec/app_templates/testapp/app/views/layouts/application.html.erb +24 -0
- data/spec/clearance/back_door_spec.rb +12 -6
- data/spec/clearance/rack_session_spec.rb +2 -0
- data/spec/clearance/session_spec.rb +91 -47
- data/spec/clearance/testing/deny_access_matcher_spec.rb +32 -0
- data/spec/configuration_spec.rb +46 -15
- data/spec/controllers/apis_controller_spec.rb +1 -5
- data/spec/controllers/forgeries_controller_spec.rb +1 -5
- data/spec/controllers/passwords_controller_spec.rb +41 -5
- data/spec/controllers/permissions_controller_spec.rb +3 -7
- data/spec/controllers/sessions_controller_spec.rb +1 -1
- data/spec/dummy/app/controllers/application_controller.rb +1 -5
- data/spec/dummy/application.rb +7 -3
- data/spec/generators/clearance/install/install_generator_spec.rb +33 -15
- data/spec/generators/clearance/views/views_generator_spec.rb +0 -2
- data/spec/models/user_spec.rb +5 -5
- data/spec/password_strategies/argon2_spec.rb +79 -0
- data/spec/password_strategies/bcrypt_spec.rb +18 -1
- data/spec/requests/authentication_cookie_spec.rb +55 -0
- data/spec/requests/token_expiration_spec.rb +5 -0
- data/spec/spec_helper.rb +4 -7
- data/spec/support/generator_spec_helpers.rb +1 -9
- metadata +51 -33
- data/app/views/layouts/application.html.erb +0 -23
- data/lib/clearance/password_strategies/bcrypt_migration_from_sha1.rb +0 -77
- data/lib/clearance/password_strategies/blowfish.rb +0 -61
- data/lib/clearance/password_strategies/sha1.rb +0 -59
- data/lib/clearance/testing.rb +0 -11
- data/lib/clearance/testing/helpers.rb +0 -15
- data/spec/app_templates/app/models/rails5/user.rb +0 -5
- data/spec/password_strategies/bcrypt_migration_from_sha1_spec.rb +0 -122
- data/spec/password_strategies/blowfish_spec.rb +0 -61
- data/spec/password_strategies/sha1_spec.rb +0 -59
- data/spec/support/environment.rb +0 -12
- data/spec/support/http_method_shim.rb +0 -25
@@ -8,7 +8,7 @@ module Clearance
|
|
8
8
|
module Matchers
|
9
9
|
# The `deny_access` matcher is used to assert that a
|
10
10
|
# request is denied access by clearance.
|
11
|
-
# @option opts [String] :flash The expected flash
|
11
|
+
# @option opts [String] :flash The expected flash alert message. Defaults
|
12
12
|
# to nil, which means the flash will not be checked.
|
13
13
|
# @option opts [String] :redirect The expected redirect url. Defaults to
|
14
14
|
# `'/'` if signed in or the `sign_in_url` if signed out.
|
@@ -78,16 +78,8 @@ module Clearance
|
|
78
78
|
@controller.request.env[:clearance]
|
79
79
|
end
|
80
80
|
|
81
|
-
def
|
82
|
-
@controller.flash[:
|
83
|
-
end
|
84
|
-
|
85
|
-
def flash_notice_value
|
86
|
-
if flash_notice.respond_to?(:values)
|
87
|
-
flash_notice.values.first
|
88
|
-
else
|
89
|
-
flash_notice
|
90
|
-
end
|
81
|
+
def flash_alert_value
|
82
|
+
@controller.flash[:alert]
|
91
83
|
end
|
92
84
|
|
93
85
|
def redirects_to_url?
|
@@ -107,16 +99,14 @@ module Clearance
|
|
107
99
|
def sets_the_flash?
|
108
100
|
if @flash.blank?
|
109
101
|
true
|
102
|
+
elsif flash_alert_value == @flash
|
103
|
+
@failure_message_when_negated <<
|
104
|
+
"Didn't expect to set the flash to #{@flash}"
|
105
|
+
true
|
110
106
|
else
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
true
|
115
|
-
else
|
116
|
-
@failure_message << "Expected the flash to be set to #{@flash} "\
|
117
|
-
"but was #{flash_notice_value}"
|
118
|
-
false
|
119
|
-
end
|
107
|
+
@failure_message << "Expected the flash to be set to #{@flash} "\
|
108
|
+
"but was #{flash_alert_value}"
|
109
|
+
false
|
120
110
|
end
|
121
111
|
end
|
122
112
|
end
|
data/lib/clearance/user.rb
CHANGED
@@ -47,9 +47,6 @@ module Clearance
|
|
47
47
|
# @return [String] The value used to identify this user in the password
|
48
48
|
# reset link.
|
49
49
|
#
|
50
|
-
# @!attribute password_changing
|
51
|
-
# @deprecated Dirty tracking is now handled automatically.
|
52
|
-
#
|
53
50
|
# @!attribute [r] password
|
54
51
|
# @return [String] Transient (non-persisted) attribute that is set when
|
55
52
|
# updating a user's password. Only the {#encrypted_password} is persisted.
|
@@ -63,7 +60,7 @@ module Clearance
|
|
63
60
|
# @see PasswordStrategies
|
64
61
|
# @return [void]
|
65
62
|
#
|
66
|
-
# @!method authenticated?
|
63
|
+
# @!method authenticated?(password)
|
67
64
|
# Check's the provided password against the user's encrypted password using
|
68
65
|
# the configured password strategy. By default, this will be
|
69
66
|
# {PasswordStrategies::BCrypt#authenticated?}, but can be changed with
|
@@ -111,24 +108,6 @@ module Clearance
|
|
111
108
|
encrypted_password_will_change!
|
112
109
|
super
|
113
110
|
end
|
114
|
-
|
115
|
-
def password_changing
|
116
|
-
warn "#{Kernel.caller.first}: [DEPRECATION] " \
|
117
|
-
"The `password_changing` attribute is deprecated. Clearance uses " \
|
118
|
-
"the dirty state of the `encrypted_password` field to track this " \
|
119
|
-
"automatically."
|
120
|
-
|
121
|
-
@password_changing
|
122
|
-
end
|
123
|
-
|
124
|
-
def password_changing=(value)
|
125
|
-
warn "#{Kernel.caller.first}: [DEPRECATION] " \
|
126
|
-
"The `password_changing` attribute is deprecated. Clearance uses " \
|
127
|
-
"the dirty state of the `encrypted_password` field to track this " \
|
128
|
-
"automatically."
|
129
|
-
|
130
|
-
@password_changing = value
|
131
|
-
end
|
132
111
|
end
|
133
112
|
|
134
113
|
# @api private
|
@@ -142,7 +121,7 @@ module Clearance
|
|
142
121
|
end
|
143
122
|
|
144
123
|
def find_by_normalized_email(email)
|
145
|
-
|
124
|
+
find_by(email: normalize_email(email))
|
146
125
|
end
|
147
126
|
|
148
127
|
def normalize_email(email)
|
@@ -164,7 +143,7 @@ module Clearance
|
|
164
143
|
validates :email,
|
165
144
|
email: { strict_mode: true },
|
166
145
|
presence: true,
|
167
|
-
uniqueness: { allow_blank: true },
|
146
|
+
uniqueness: { allow_blank: true, case_sensitive: false },
|
168
147
|
unless: :email_optional?
|
169
148
|
|
170
149
|
validates :password, presence: true, unless: :skip_password_validation?
|
data/lib/clearance/version.rb
CHANGED
@@ -102,11 +102,7 @@ module Clearance
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def users_table_exists?
|
105
|
-
|
106
|
-
ActiveRecord::Base.connection.data_source_exists?(:users)
|
107
|
-
else
|
108
|
-
ActiveRecord::Base.connection.table_exists?(:users)
|
109
|
-
end
|
105
|
+
ActiveRecord::Base.connection.data_source_exists?(:users)
|
110
106
|
end
|
111
107
|
|
112
108
|
def existing_users_columns
|
@@ -123,17 +119,21 @@ module Clearance
|
|
123
119
|
end
|
124
120
|
|
125
121
|
def migration_version
|
126
|
-
|
127
|
-
|
122
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
123
|
+
end
|
124
|
+
|
125
|
+
def migration_primary_key_type_string
|
126
|
+
if configured_key_type
|
127
|
+
", id: :#{configured_key_type}"
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
+
def configured_key_type
|
132
|
+
Rails.configuration.generators.active_record[:primary_key_type]
|
133
|
+
end
|
134
|
+
|
131
135
|
def models_inherit_from
|
132
|
-
|
133
|
-
"ApplicationRecord"
|
134
|
-
else
|
135
|
-
"ActiveRecord::Base"
|
136
|
-
end
|
136
|
+
"ApplicationRecord"
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
@@ -8,9 +8,11 @@ Next steps:
|
|
8
8
|
# config/environments/{development,test}.rb
|
9
9
|
config.action_mailer.default_url_options = { host: 'localhost:3000' }
|
10
10
|
|
11
|
-
In production it should be your
|
11
|
+
In the production environment it should be your application's full hostname.
|
12
12
|
|
13
|
-
2. Display user session
|
13
|
+
2. Display user session status.
|
14
|
+
|
15
|
+
From somewhere in your layout, render sign in and sign out buttons:
|
14
16
|
|
15
17
|
<% if signed_in? %>
|
16
18
|
Signed in as: <%= current_user.email %>
|
@@ -19,14 +21,18 @@ Next steps:
|
|
19
21
|
<%= link_to 'Sign in', sign_in_path %>
|
20
22
|
<% end %>
|
21
23
|
|
24
|
+
3. Render the flash contents.
|
25
|
+
|
26
|
+
Make sure the flash is being rendered in your views using something like:
|
27
|
+
|
22
28
|
<div id="flash">
|
23
29
|
<% flash.each do |key, value| %>
|
24
30
|
<div class="flash <%= key %>"><%= value %></div>
|
25
31
|
<% end %>
|
26
32
|
</div>
|
27
33
|
|
28
|
-
|
34
|
+
4. Migrate:
|
29
35
|
|
30
|
-
rails db:migrate
|
36
|
+
Run `rails db:migrate` to add the clearance database changes.
|
31
37
|
|
32
38
|
*******************************************************************************
|
@@ -13,7 +13,7 @@ class AddClearanceToUsers < ActiveRecord::Migration<%= migration_version %>
|
|
13
13
|
users = select_all("SELECT id FROM users WHERE remember_token IS NULL")
|
14
14
|
|
15
15
|
users.each do |user|
|
16
|
-
update <<-SQL
|
16
|
+
update <<-SQL.squish
|
17
17
|
UPDATE users
|
18
18
|
SET remember_token = '#{Clearance::Token.new}'
|
19
19
|
WHERE id = '#{user['id']}'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class CreateUsers < ActiveRecord::Migration<%= migration_version %>
|
2
2
|
def change
|
3
|
-
create_table :users do |t|
|
3
|
+
create_table :users<%= migration_primary_key_type_string %> do |t|
|
4
4
|
t.timestamps null: false
|
5
5
|
t.string :email, null: false
|
6
6
|
t.string :encrypted_password, limit: 128, null: false
|
@@ -36,9 +36,6 @@ describe "Clearance Installation" do
|
|
36
36
|
--skip-keeps
|
37
37
|
--skip-sprockets
|
38
38
|
CMD
|
39
|
-
|
40
|
-
FileUtils.rm_f("public/index.html")
|
41
|
-
FileUtils.rm_f("app/views/layouts/application.html.erb")
|
42
39
|
end
|
43
40
|
|
44
41
|
def testapp_templates
|
@@ -47,7 +44,6 @@ describe "Clearance Installation" do
|
|
47
44
|
|
48
45
|
def configure_test_app
|
49
46
|
FileUtils.rm_f("public/index.html")
|
50
|
-
FileUtils.rm_f("app/views/layouts/application.html.erb")
|
51
47
|
FileUtils.cp_r(testapp_templates, "..")
|
52
48
|
end
|
53
49
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<%= javascript_include_tag 'application' %>
|
5
|
+
<%= csrf_meta_tag %>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div id="header">
|
9
|
+
<% if signed_in? -%>
|
10
|
+
<%= button_to t(".sign_out"), sign_out_path, method: :delete %>
|
11
|
+
<% else -%>
|
12
|
+
<%= link_to t(".sign_in"), sign_in_path %>
|
13
|
+
<% end -%>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div id="flash">
|
17
|
+
<% flash.each do |key, value| -%>
|
18
|
+
<div id="flash_<%= key %>"><%=h value %></div>
|
19
|
+
<% end %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<%= yield %>
|
23
|
+
</body>
|
24
|
+
</html>
|
@@ -1,9 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
require "support/environment"
|
3
2
|
|
4
3
|
describe Clearance::BackDoor do
|
5
|
-
include EnvironmentSupport
|
6
|
-
|
7
4
|
it "signs in as a given user" do
|
8
5
|
user_id = "123"
|
9
6
|
user = double("user")
|
@@ -42,7 +39,7 @@ describe Clearance::BackDoor do
|
|
42
39
|
end
|
43
40
|
|
44
41
|
it "can't be used outside the allowed environments" do
|
45
|
-
with_environment("
|
42
|
+
with_environment("production") do
|
46
43
|
expect { Clearance::BackDoor.new(mock_app) }.
|
47
44
|
to raise_exception "Can't use auth backdoor outside of configured \
|
48
45
|
environments (test, ci, development).".squish
|
@@ -55,7 +52,7 @@ describe Clearance::BackDoor do
|
|
55
52
|
end
|
56
53
|
|
57
54
|
it "raises an error for a default allowed env" do
|
58
|
-
with_environment("
|
55
|
+
with_environment("test") do
|
59
56
|
expect { Clearance::BackDoor.new(mock_app) }.
|
60
57
|
to raise_exception "BackDoor auth is disabled."
|
61
58
|
end
|
@@ -68,7 +65,7 @@ describe Clearance::BackDoor do
|
|
68
65
|
end
|
69
66
|
|
70
67
|
it "can be used with configured allowed environments" do
|
71
|
-
with_environment("
|
68
|
+
with_environment("demo") do
|
72
69
|
user_id = "123"
|
73
70
|
user = double("user")
|
74
71
|
allow(User).to receive(:find).with(user_id).and_return(user)
|
@@ -100,4 +97,13 @@ describe Clearance::BackDoor do
|
|
100
97
|
def mock_app
|
101
98
|
lambda { |env| [200, {}, ["okay"]] }
|
102
99
|
end
|
100
|
+
|
101
|
+
def with_environment(environment)
|
102
|
+
original_env = Rails.env
|
103
|
+
Rails.env = environment
|
104
|
+
|
105
|
+
yield
|
106
|
+
ensure
|
107
|
+
Rails.env = original_env
|
108
|
+
end
|
103
109
|
end
|
@@ -11,6 +11,8 @@ describe Clearance::RackSession do
|
|
11
11
|
env = Rack::MockRequest.env_for('/')
|
12
12
|
expected_session = "the session"
|
13
13
|
allow(expected_session).to receive(:add_cookie_to_headers)
|
14
|
+
allow(expected_session).to receive(:authentication_successful?).
|
15
|
+
and_return(true)
|
14
16
|
allow(Clearance::Session).to receive(:new).
|
15
17
|
with(env).
|
16
18
|
and_return(expected_session)
|
@@ -129,6 +129,12 @@ describe Clearance::Session do
|
|
129
129
|
|
130
130
|
def stub_guard_class(guard)
|
131
131
|
double("guard_class").tap do |guard_class|
|
132
|
+
allow(guard_class).to receive(:to_s).
|
133
|
+
and_return(guard_class)
|
134
|
+
|
135
|
+
allow(guard_class).to receive(:constantize).
|
136
|
+
and_return(guard_class)
|
137
|
+
|
132
138
|
allow(guard_class).to receive(:new).
|
133
139
|
with(session, stub_default_sign_in_guard).
|
134
140
|
and_return(guard)
|
@@ -170,6 +176,31 @@ describe Clearance::Session do
|
|
170
176
|
end
|
171
177
|
end
|
172
178
|
|
179
|
+
context "if same_site is set" do
|
180
|
+
before do
|
181
|
+
Clearance.configuration.same_site = :lax
|
182
|
+
session.sign_in(user)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "sets a same-site cookie" do
|
186
|
+
session.add_cookie_to_headers(headers)
|
187
|
+
|
188
|
+
expect(headers["Set-Cookie"]).to match(/remember_token=.+; SameSite/)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context "if same_site is not set" do
|
193
|
+
before do
|
194
|
+
session.sign_in(user)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "sets a standard cookie" do
|
198
|
+
session.add_cookie_to_headers(headers)
|
199
|
+
|
200
|
+
expect(headers["Set-Cookie"]).to_not match(/remember_token=.+; SameSite/)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
173
204
|
describe 'remember token cookie expiration' do
|
174
205
|
context 'default configuration' do
|
175
206
|
it 'is set to 1 year from now' do
|
@@ -186,37 +217,6 @@ describe Clearance::Session do
|
|
186
217
|
end
|
187
218
|
end
|
188
219
|
|
189
|
-
context 'configured with lambda taking no arguments' do
|
190
|
-
it 'logs a deprecation warning' do
|
191
|
-
expiration = -> { Time.now }
|
192
|
-
with_custom_expiration expiration do
|
193
|
-
session = Clearance::Session.new(env_without_remember_token)
|
194
|
-
session.sign_in user
|
195
|
-
allow(session).to receive(:warn)
|
196
|
-
session.add_cookie_to_headers headers
|
197
|
-
|
198
|
-
expect(session).to have_received(:warn).once
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
it 'is set to the value of the evaluated lambda' do
|
203
|
-
expires_at = -> { 1.day.from_now }
|
204
|
-
with_custom_expiration expires_at do
|
205
|
-
user = double("User", remember_token: "123abc")
|
206
|
-
headers = {}
|
207
|
-
session = Clearance::Session.new(env_without_remember_token)
|
208
|
-
session.sign_in user
|
209
|
-
allow(session).to receive(:warn)
|
210
|
-
session.add_cookie_to_headers headers
|
211
|
-
|
212
|
-
expect(headers).to set_cookie(
|
213
|
-
'remember_token',
|
214
|
-
user.remember_token, expires_at.call
|
215
|
-
)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
220
|
context 'configured with lambda taking one argument' do
|
221
221
|
it 'it can use other cookies to set the value of the expires token' do
|
222
222
|
remembered_expires = 12.hours.from_now
|
@@ -269,17 +269,31 @@ describe Clearance::Session do
|
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
272
|
-
describe
|
273
|
-
context
|
272
|
+
describe "cookie domain option" do
|
273
|
+
context "when set" do
|
274
274
|
before do
|
275
|
-
Clearance.configuration.cookie_domain =
|
275
|
+
Clearance.configuration.cookie_domain = cookie_domain
|
276
276
|
session.sign_in(user)
|
277
277
|
end
|
278
278
|
|
279
|
-
|
280
|
-
|
279
|
+
context "with string" do
|
280
|
+
let(:cookie_domain) { ".example.com" }
|
281
|
+
|
282
|
+
it "sets a standard cookie" do
|
283
|
+
session.add_cookie_to_headers(headers)
|
284
|
+
|
285
|
+
expect(headers['Set-Cookie']).to match(/domain=\.example\.com; path/)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context "with lambda" do
|
290
|
+
let(:cookie_domain) { lambda { |_r| ".example.com" } }
|
281
291
|
|
282
|
-
|
292
|
+
it "sets a standard cookie" do
|
293
|
+
session.add_cookie_to_headers(headers)
|
294
|
+
|
295
|
+
expect(headers['Set-Cookie']).to match(/domain=\.example\.com; path/)
|
296
|
+
end
|
283
297
|
end
|
284
298
|
end
|
285
299
|
|
@@ -289,7 +303,7 @@ describe Clearance::Session do
|
|
289
303
|
it 'sets a standard cookie' do
|
290
304
|
session.add_cookie_to_headers(headers)
|
291
305
|
|
292
|
-
expect(headers[
|
306
|
+
expect(headers["Set-Cookie"]).not_to match(/domain=.+; path/)
|
293
307
|
end
|
294
308
|
end
|
295
309
|
end
|
@@ -301,7 +315,7 @@ describe Clearance::Session do
|
|
301
315
|
it 'sets a standard cookie' do
|
302
316
|
session.add_cookie_to_headers(headers)
|
303
317
|
|
304
|
-
expect(headers[
|
318
|
+
expect(headers["Set-Cookie"]).to_not match(/domain=.+; path/)
|
305
319
|
end
|
306
320
|
end
|
307
321
|
|
@@ -326,14 +340,44 @@ describe Clearance::Session do
|
|
326
340
|
expect(headers["Set-Cookie"]).to be nil
|
327
341
|
end
|
328
342
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
343
|
+
describe "#sign_out" do
|
344
|
+
it "signs out a user" do
|
345
|
+
user = create(:user)
|
346
|
+
old_remember_token = user.remember_token
|
347
|
+
env = env_with_remember_token(old_remember_token)
|
348
|
+
session = Clearance::Session.new(env)
|
349
|
+
cookie_jar = ActionDispatch::Request.new(env).cookie_jar
|
350
|
+
expect(cookie_jar.deleted?(:remember_token)).to be false
|
351
|
+
|
352
|
+
session.sign_out
|
353
|
+
|
354
|
+
expect(cookie_jar.deleted?(:remember_token)).to be true
|
355
|
+
expect(session.current_user).to be_nil
|
356
|
+
expect(user.reload.remember_token).not_to eq old_remember_token
|
357
|
+
end
|
358
|
+
|
359
|
+
context "with custom cookie domain" do
|
360
|
+
let(:domain) { ".example.com" }
|
361
|
+
|
362
|
+
before do
|
363
|
+
Clearance.configuration.cookie_domain = domain
|
364
|
+
end
|
365
|
+
|
366
|
+
it "clears cookie" do
|
367
|
+
user = create(:user)
|
368
|
+
env = env_with_remember_token(
|
369
|
+
value: user.remember_token,
|
370
|
+
domain: domain,
|
371
|
+
)
|
372
|
+
session = Clearance::Session.new(env)
|
373
|
+
cookie_jar = ActionDispatch::Request.new(env).cookie_jar
|
374
|
+
expect(cookie_jar.deleted?(:remember_token, domain: domain)).to be false
|
375
|
+
|
376
|
+
session.sign_out
|
377
|
+
|
378
|
+
expect(cookie_jar.deleted?(:remember_token, domain: domain)).to be true
|
379
|
+
end
|
380
|
+
end
|
337
381
|
end
|
338
382
|
|
339
383
|
def env_with_cookies(cookies)
|