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
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class PretendFriendsController < ActionController::Base
|
4
|
+
include Clearance::Controller
|
5
|
+
before_action :require_login
|
6
|
+
|
7
|
+
def index
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe PretendFriendsController, type: :controller do
|
12
|
+
before do
|
13
|
+
Rails.application.routes.draw do
|
14
|
+
resources :pretend_friends, only: :index
|
15
|
+
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
Rails.application.reload_routes!
|
21
|
+
end
|
22
|
+
|
23
|
+
it "checks contents of deny access flash" do
|
24
|
+
get :index
|
25
|
+
|
26
|
+
expect(subject).to deny_access(flash: failure_message)
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message
|
30
|
+
I18n.t("flashes.failure_when_not_signed_in")
|
31
|
+
end
|
32
|
+
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Clearance::Configuration do
|
4
|
+
let(:config) { Clearance.configuration }
|
5
|
+
|
4
6
|
context "when no user_model_name is specified" do
|
5
7
|
it "defaults to User" do
|
6
8
|
expect(Clearance.configuration.user_model).to eq ::User
|
@@ -8,12 +10,47 @@ describe Clearance::Configuration do
|
|
8
10
|
end
|
9
11
|
|
10
12
|
context "when a custom user_model_name is specified" do
|
11
|
-
|
13
|
+
before(:each) do
|
12
14
|
MyUser = Class.new
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
Object.send(:remove_const, :MyUser)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is used instead of User" do
|
13
22
|
Clearance.configure { |config| config.user_model = MyUser }
|
14
23
|
|
15
24
|
expect(Clearance.configuration.user_model).to eq ::MyUser
|
16
25
|
end
|
26
|
+
|
27
|
+
it "can be specified as a string to avoid triggering autoloading" do
|
28
|
+
Clearance.configure { |config| config.user_model = "MyUser" }
|
29
|
+
|
30
|
+
expect(Clearance.configuration.user_model).to eq ::MyUser
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when no parent_controller is specified" do
|
35
|
+
it "defaults to ApplicationController" do
|
36
|
+
expect(config.parent_controller).to eq ::ApplicationController
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when a custom parent_controller is specified" do
|
41
|
+
before(:each) do
|
42
|
+
MyController = Class.new
|
43
|
+
end
|
44
|
+
|
45
|
+
after(:each) do
|
46
|
+
Object.send(:remove_const, :MyController)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "is used instead of ApplicationController" do
|
50
|
+
Clearance.configure { |config| config.parent_controller = MyController }
|
51
|
+
|
52
|
+
expect(config.parent_controller).to eq ::MyController
|
53
|
+
end
|
17
54
|
end
|
18
55
|
|
19
56
|
context "when secure_cookie is set to true" do
|
@@ -146,28 +183,22 @@ describe Clearance::Configuration do
|
|
146
183
|
end
|
147
184
|
|
148
185
|
describe "#rotate_csrf_on_sign_in?" do
|
149
|
-
it "
|
150
|
-
Clearance.configuration = Clearance::Configuration.new
|
151
|
-
allow(Clearance.configuration).to receive(:warn)
|
152
|
-
|
153
|
-
expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be_falsey
|
154
|
-
expect(Clearance.configuration).to have_received(:warn)
|
155
|
-
end
|
156
|
-
|
157
|
-
it "is true and does not warn when `rotate_csrf_on_sign_in` is true" do
|
186
|
+
it "is true when `rotate_csrf_on_sign_in` is set to true" do
|
158
187
|
Clearance.configure { |config| config.rotate_csrf_on_sign_in = true }
|
159
|
-
allow(Clearance.configuration).to receive(:warn)
|
160
188
|
|
161
189
|
expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be true
|
162
|
-
expect(Clearance.configuration).not_to have_received(:warn)
|
163
190
|
end
|
164
191
|
|
165
|
-
it "is false
|
192
|
+
it "is false when `rotate_csrf_on_sign_in` is set to false" do
|
166
193
|
Clearance.configure { |config| config.rotate_csrf_on_sign_in = false }
|
167
|
-
allow(Clearance.configuration).to receive(:warn)
|
168
194
|
|
169
195
|
expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be false
|
170
|
-
|
196
|
+
end
|
197
|
+
|
198
|
+
it "is false when `rotate_csrf_on_sign_in` is set to nil" do
|
199
|
+
Clearance.configure { |config| config.rotate_csrf_on_sign_in = nil }
|
200
|
+
|
201
|
+
expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be false
|
171
202
|
end
|
172
203
|
end
|
173
204
|
end
|
@@ -3,11 +3,7 @@ require 'spec_helper'
|
|
3
3
|
class ApisController < ActionController::Base
|
4
4
|
include Clearance::Controller
|
5
5
|
|
6
|
-
|
7
|
-
before_action :require_login
|
8
|
-
else
|
9
|
-
before_filter :require_login
|
10
|
-
end
|
6
|
+
before_action :require_login
|
11
7
|
|
12
8
|
def show
|
13
9
|
head :ok
|
@@ -5,11 +5,7 @@ class ForgeriesController < ActionController::Base
|
|
5
5
|
|
6
6
|
protect_from_forgery
|
7
7
|
|
8
|
-
|
9
|
-
before_action :require_login
|
10
|
-
else
|
11
|
-
before_filter :require_login
|
12
|
-
end
|
8
|
+
before_action :require_login
|
13
9
|
|
14
10
|
# This is off in test by default, but we need it for this test
|
15
11
|
self.allow_forgery_protection = true
|
@@ -37,6 +37,30 @@ describe Clearance::PasswordsController do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
context "email param is missing" do
|
41
|
+
it "displays flash error on new page" do
|
42
|
+
post :create, params: {
|
43
|
+
password: {},
|
44
|
+
}
|
45
|
+
|
46
|
+
expect(flash.now[:alert]).to match(/email can't be blank/i)
|
47
|
+
expect(response).to render_template(:new)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "email param is blank" do
|
52
|
+
it "displays flash error on new page" do
|
53
|
+
post :create, params: {
|
54
|
+
password: {
|
55
|
+
email: "",
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
expect(flash.now[:alert]).to match(/email can't be blank/i)
|
60
|
+
expect(response).to render_template(:new)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
40
64
|
context "email does not belong to an existing user" do
|
41
65
|
it "does not deliver an email" do
|
42
66
|
ActionMailer::Base.deliveries.clear
|
@@ -94,19 +118,19 @@ describe Clearance::PasswordsController do
|
|
94
118
|
end
|
95
119
|
|
96
120
|
context "blank token is supplied" do
|
97
|
-
it "renders the new password reset form with a flash
|
121
|
+
it "renders the new password reset form with a flash alert" do
|
98
122
|
get :edit, params: {
|
99
123
|
user_id: 1,
|
100
124
|
token: "",
|
101
125
|
}
|
102
126
|
|
103
127
|
expect(response).to render_template(:new)
|
104
|
-
expect(flash.now[:
|
128
|
+
expect(flash.now[:alert]).to match(/double check the URL/i)
|
105
129
|
end
|
106
130
|
end
|
107
131
|
|
108
132
|
context "invalid token is supplied" do
|
109
|
-
it "renders the new password reset form with a flash
|
133
|
+
it "renders the new password reset form with a flash alert" do
|
110
134
|
user = create(:user, :with_forgotten_password)
|
111
135
|
|
112
136
|
get :edit, params: {
|
@@ -115,7 +139,7 @@ describe Clearance::PasswordsController do
|
|
115
139
|
}
|
116
140
|
|
117
141
|
expect(response).to render_template(:new)
|
118
|
-
expect(flash.now[:
|
142
|
+
expect(flash.now[:alert]).to match(/double check the URL/i)
|
119
143
|
end
|
120
144
|
end
|
121
145
|
|
@@ -166,6 +190,18 @@ describe Clearance::PasswordsController do
|
|
166
190
|
expect(user.confirmation_token).to be_present
|
167
191
|
end
|
168
192
|
|
193
|
+
it "does not raise NoMethodError from incomplete password_reset params" do
|
194
|
+
user = create(:user, :with_forgotten_password)
|
195
|
+
|
196
|
+
expect do
|
197
|
+
put :update, params: {
|
198
|
+
user_id: user,
|
199
|
+
token: user.confirmation_token,
|
200
|
+
password_reset: {},
|
201
|
+
}
|
202
|
+
end.not_to raise_error
|
203
|
+
end
|
204
|
+
|
169
205
|
it "re-renders the password edit form" do
|
170
206
|
user = create(:user, :with_forgotten_password)
|
171
207
|
|
@@ -174,7 +210,7 @@ describe Clearance::PasswordsController do
|
|
174
210
|
new_password: "",
|
175
211
|
)
|
176
212
|
|
177
|
-
expect(flash.now[:
|
213
|
+
expect(flash.now[:alert]).to match(/password can't be blank/i)
|
178
214
|
expect(response).to render_template(:edit)
|
179
215
|
expect(cookies[:remember_token]).to be_nil
|
180
216
|
end
|
@@ -3,11 +3,7 @@ require 'spec_helper'
|
|
3
3
|
class PermissionsController < ActionController::Base
|
4
4
|
include Clearance::Controller
|
5
5
|
|
6
|
-
|
7
|
-
before_action :require_login, only: :show
|
8
|
-
else
|
9
|
-
before_filter :require_login, only: :show
|
10
|
-
end
|
6
|
+
before_action :require_login, only: :show
|
11
7
|
|
12
8
|
def new
|
13
9
|
head :ok
|
@@ -62,14 +58,14 @@ describe PermissionsController do
|
|
62
58
|
it "denies access to show and display a flash message" do
|
63
59
|
get :show
|
64
60
|
|
65
|
-
expect(flash[:
|
61
|
+
expect(flash[:alert]).to match(/^Please sign in to continue/)
|
66
62
|
end
|
67
63
|
end
|
68
64
|
|
69
65
|
context 'when remember_token is blank' do
|
70
66
|
it 'denies acess to show' do
|
71
67
|
user = create(:user)
|
72
|
-
user.
|
68
|
+
user.update(remember_token: '')
|
73
69
|
cookies[:remember_token] = ''
|
74
70
|
|
75
71
|
get :show
|
@@ -2,10 +2,6 @@ class ApplicationController < ActionController::Base
|
|
2
2
|
include Clearance::Controller
|
3
3
|
|
4
4
|
def show
|
5
|
-
|
6
|
-
render html: "", layout: "application"
|
7
|
-
else
|
8
|
-
render text: "", layout: "application"
|
9
|
-
end
|
5
|
+
render inline: "Hello user #<%= current_user.id %>", layout: false
|
10
6
|
end
|
11
7
|
end
|
data/spec/dummy/application.rb
CHANGED
@@ -28,13 +28,17 @@ module Dummy
|
|
28
28
|
config.secret_key_base = "SECRET_KEY_BASE"
|
29
29
|
|
30
30
|
if config.active_record.sqlite3.respond_to?(:represent_boolean_as_integer)
|
31
|
-
|
31
|
+
if Rails::VERSION::MAJOR < 6
|
32
|
+
config.active_record.sqlite3.represent_boolean_as_integer = true
|
33
|
+
end
|
32
34
|
end
|
33
35
|
|
34
|
-
if
|
35
|
-
config.
|
36
|
+
if Rails::VERSION::MAJOR >= 6
|
37
|
+
config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"
|
36
38
|
end
|
37
39
|
|
40
|
+
config.active_job.queue_adapter = :inline
|
41
|
+
|
38
42
|
def require_environment!
|
39
43
|
initialize!
|
40
44
|
end
|
@@ -70,7 +70,30 @@ describe Clearance::Generators::InstallGenerator, :generator do
|
|
70
70
|
|
71
71
|
expect(migration).to exist
|
72
72
|
expect(migration).to have_correct_syntax
|
73
|
-
expect(migration).to contain("create_table :users")
|
73
|
+
expect(migration).to contain("create_table :users do")
|
74
|
+
end
|
75
|
+
|
76
|
+
context "active record configured for uuid" do
|
77
|
+
around do |example|
|
78
|
+
preserve_original_primary_key_type_setting do
|
79
|
+
Rails.application.config.generators do |g|
|
80
|
+
g.orm :active_record, primary_key_type: :uuid
|
81
|
+
end
|
82
|
+
example.run
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "creates a migration to create the users table with key type set" do
|
87
|
+
provide_existing_application_controller
|
88
|
+
table_does_not_exist(:users)
|
89
|
+
|
90
|
+
run_generator
|
91
|
+
migration = migration_file("db/migrate/create_users.rb")
|
92
|
+
|
93
|
+
expect(migration).to exist
|
94
|
+
expect(migration).to have_correct_syntax
|
95
|
+
expect(migration).to contain("create_table :users, id: :uuid do")
|
96
|
+
end
|
74
97
|
end
|
75
98
|
end
|
76
99
|
|
@@ -118,16 +141,15 @@ describe Clearance::Generators::InstallGenerator, :generator do
|
|
118
141
|
|
119
142
|
def table_does_not_exist(name)
|
120
143
|
connection = ActiveRecord::Base.connection
|
144
|
+
allow(connection).to receive(:data_source_exists?).
|
145
|
+
with(name).
|
146
|
+
and_return(false)
|
147
|
+
end
|
121
148
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
else
|
127
|
-
allow(connection).to receive(:table_exists?).
|
128
|
-
with(name).
|
129
|
-
and_return(false)
|
130
|
-
end
|
149
|
+
def preserve_original_primary_key_type_setting
|
150
|
+
original = Rails.configuration.generators.active_record[:primary_key_type]
|
151
|
+
yield
|
152
|
+
Rails.configuration.generators.active_record[:primary_key_type] = original
|
131
153
|
end
|
132
154
|
|
133
155
|
def contain_models_inherit_from
|
@@ -135,10 +157,6 @@ describe Clearance::Generators::InstallGenerator, :generator do
|
|
135
157
|
end
|
136
158
|
|
137
159
|
def models_inherit_from
|
138
|
-
|
139
|
-
"ApplicationRecord"
|
140
|
-
else
|
141
|
-
"ActiveRecord::Base"
|
142
|
-
end
|
160
|
+
"ApplicationRecord"
|
143
161
|
end
|
144
162
|
end
|
@@ -8,7 +8,6 @@ describe Clearance::Generators::ViewsGenerator, :generator do
|
|
8
8
|
views = %w(
|
9
9
|
clearance_mailer/change_password.html.erb
|
10
10
|
clearance_mailer/change_password.text.erb
|
11
|
-
layouts/application.html.erb
|
12
11
|
passwords/create.html.erb
|
13
12
|
passwords/edit.html.erb
|
14
13
|
passwords/new.html.erb
|
@@ -22,7 +21,6 @@ describe Clearance::Generators::ViewsGenerator, :generator do
|
|
22
21
|
|
23
22
|
view_files.each do |each|
|
24
23
|
expect(each).to exist
|
25
|
-
expect(each).to have_correct_syntax
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
data/spec/models/user_spec.rb
CHANGED
@@ -5,15 +5,15 @@ describe User do
|
|
5
5
|
it { is_expected.to have_db_index(:remember_token) }
|
6
6
|
it { is_expected.to validate_presence_of(:email) }
|
7
7
|
it { is_expected.to validate_presence_of(:password) }
|
8
|
+
it { is_expected.to allow_value("foo;@example.com").for(:email) }
|
9
|
+
it { is_expected.to allow_value("foo@.example.com").for(:email) }
|
10
|
+
it { is_expected.to allow_value("foo@example..com").for(:email) }
|
8
11
|
it { is_expected.to allow_value("foo@example.co.uk").for(:email) }
|
9
12
|
it { is_expected.to allow_value("foo@example.com").for(:email) }
|
10
13
|
it { is_expected.to allow_value("foo+bar@example.com").for(:email) }
|
11
|
-
it { is_expected.not_to allow_value("foo@").for(:email) }
|
12
|
-
it { is_expected.not_to allow_value("foo@example..com").for(:email) }
|
13
|
-
it { is_expected.not_to allow_value("foo@.example.com").for(:email) }
|
14
|
-
it { is_expected.not_to allow_value("foo").for(:email) }
|
15
14
|
it { is_expected.not_to allow_value("example.com").for(:email) }
|
16
|
-
it { is_expected.not_to allow_value("foo
|
15
|
+
it { is_expected.not_to allow_value("foo").for(:email) }
|
16
|
+
it { is_expected.not_to allow_value("foo@").for(:email) }
|
17
17
|
|
18
18
|
describe "#email" do
|
19
19
|
it "stores email in down case and removes whitespace" do
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Clearance::PasswordStrategies::Argon2 do
|
4
|
+
include FakeModelWithPasswordStrategy
|
5
|
+
|
6
|
+
describe "#password=" do
|
7
|
+
it "encrypts the password into encrypted_password" do
|
8
|
+
stub_argon2_password
|
9
|
+
model_instance = fake_model_with_argon2_strategy
|
10
|
+
|
11
|
+
model_instance.password = password
|
12
|
+
|
13
|
+
expect(model_instance.encrypted_password).to eq encrypted_password
|
14
|
+
end
|
15
|
+
|
16
|
+
it "encrypts with Argon2 using default cost in non test environments" do
|
17
|
+
hasher = stub_argon2_password
|
18
|
+
model_instance = fake_model_with_argon2_strategy
|
19
|
+
allow(Rails).to receive(:env).
|
20
|
+
and_return(ActiveSupport::StringInquirer.new("production"))
|
21
|
+
|
22
|
+
model_instance.password = password
|
23
|
+
|
24
|
+
expect(hasher).to have_received(:create).with(password)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "encrypts with Argon2 using minimum cost in test environment" do
|
28
|
+
hasher = stub_argon2_password
|
29
|
+
model_instance = fake_model_with_argon2_strategy
|
30
|
+
|
31
|
+
model_instance.password = password
|
32
|
+
|
33
|
+
expect(hasher).to have_received(:create).with(password)
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub_argon2_password
|
37
|
+
hasher = double(Argon2::Password)
|
38
|
+
allow(hasher).to receive(:create).and_return(encrypted_password)
|
39
|
+
allow(Argon2::Password).to receive(:new).and_return(hasher)
|
40
|
+
hasher
|
41
|
+
end
|
42
|
+
|
43
|
+
def encrypted_password
|
44
|
+
@encrypted_password ||= double("encrypted password")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#authenticated?" do
|
49
|
+
context "given a password" do
|
50
|
+
it "is authenticated with Argon2" do
|
51
|
+
model_instance = fake_model_with_argon2_strategy
|
52
|
+
|
53
|
+
model_instance.password = password
|
54
|
+
|
55
|
+
expect(model_instance).to be_authenticated(password)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "given no password" do
|
60
|
+
it "is not authenticated" do
|
61
|
+
model_instance = fake_model_with_argon2_strategy
|
62
|
+
|
63
|
+
password = nil
|
64
|
+
|
65
|
+
expect(model_instance).not_to be_authenticated(password)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def fake_model_with_argon2_strategy
|
71
|
+
@fake_model_with_argon2_strategy ||= fake_model_with_password_strategy(
|
72
|
+
Clearance::PasswordStrategies::Argon2,
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def password
|
77
|
+
"password"
|
78
|
+
end
|
79
|
+
end
|