clearance 2.10.0 → 2.11.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.
- checksums.yaml +4 -4
- data/.github/workflows/codeql.yml +39 -0
- data/.github/workflows/standardrb.yml +19 -0
- data/.github/workflows/tests.yml +4 -3
- data/Appraisals +1 -1
- data/CHANGELOG.md +21 -1
- data/CODEOWNERS +2 -0
- data/Gemfile +17 -14
- data/Gemfile.lock +117 -85
- data/README.md +1 -2
- data/Rakefile +1 -1
- data/app/controllers/clearance/passwords_controller.rb +6 -6
- data/app/mailers/clearance_mailer.rb +1 -1
- data/clearance.gemspec +38 -38
- data/config/routes.rb +7 -7
- data/gemfiles/rails_7.1.gemfile +3 -0
- data/gemfiles/rails_7.2.gemfile +3 -0
- data/gemfiles/rails_8.0.gemfile +5 -1
- data/lib/clearance/authentication.rb +4 -0
- data/lib/clearance/back_door.rb +3 -3
- data/lib/clearance/configuration.rb +6 -6
- data/lib/clearance/constraints.rb +2 -2
- data/lib/clearance/controller.rb +2 -2
- data/lib/clearance/default_sign_in_guard.rb +1 -1
- data/lib/clearance/password_strategies/bcrypt.rb +2 -2
- data/lib/clearance/session.rb +4 -6
- data/lib/clearance/sign_in_guard.rb +1 -1
- data/lib/clearance/testing/deny_access_matcher.rb +4 -4
- data/lib/clearance/token.rb +1 -1
- data/lib/clearance/user.rb +7 -7
- data/lib/clearance/version.rb +1 -1
- data/lib/clearance.rb +10 -10
- data/lib/generators/clearance/install/install_generator.rb +15 -15
- data/lib/generators/clearance/routes/routes_generator.rb +5 -5
- data/lib/generators/clearance/routes/templates/routes.rb +10 -10
- data/lib/generators/clearance/specs/specs_generator.rb +4 -4
- data/lib/generators/clearance/views/views_generator.rb +4 -4
- data/spec/acceptance/clearance_installation_spec.rb +3 -3
- data/spec/clearance/back_door_spec.rb +5 -5
- data/spec/clearance/constraints/signed_in_spec.rb +14 -14
- data/spec/clearance/constraints/signed_out_spec.rb +4 -4
- data/spec/clearance/default_sign_in_guard_spec.rb +6 -6
- data/spec/clearance/rack_session_spec.rb +9 -9
- data/spec/clearance/session_spec.rb +60 -62
- data/spec/clearance/sign_in_guard_spec.rb +7 -7
- data/spec/clearance/testing/controller_helpers_spec.rb +15 -14
- data/spec/clearance/testing/deny_access_matcher_spec.rb +1 -1
- data/spec/clearance/testing/view_helpers_spec.rb +2 -2
- data/spec/clearance/token_spec.rb +3 -3
- data/spec/configuration_spec.rb +8 -21
- data/spec/controllers/apis_controller_spec.rb +2 -2
- data/spec/controllers/forgeries_controller_spec.rb +12 -12
- data/spec/controllers/passwords_controller_spec.rb +25 -25
- data/spec/controllers/permissions_controller_spec.rb +12 -12
- data/spec/controllers/sessions_controller_spec.rb +6 -6
- data/spec/controllers/users_controller_spec.rb +5 -5
- data/spec/dummy/config/environments/test.rb +3 -3
- data/spec/factories/users.rb +3 -3
- data/spec/generators/clearance/install/install_generator_spec.rb +11 -11
- data/spec/generators/clearance/routes/routes_generator_spec.rb +1 -1
- data/spec/generators/clearance/specs/specs_generator_spec.rb +2 -2
- data/spec/generators/clearance/views/views_generator_spec.rb +2 -2
- data/spec/mailers/clearance_mailer_spec.rb +3 -2
- data/spec/models/user_spec.rb +2 -2
- data/spec/password_strategies/argon2_spec.rb +3 -3
- data/spec/password_strategies/bcrypt_spec.rb +4 -4
- data/spec/password_strategies/password_strategies_spec.rb +1 -1
- data/spec/requests/authentication_cookie_spec.rb +3 -3
- data/spec/requests/backdoor_spec.rb +1 -1
- data/spec/requests/cookie_options_spec.rb +2 -2
- data/spec/requests/csrf_rotation_spec.rb +1 -1
- data/spec/requests/password_maintenance_spec.rb +1 -1
- data/spec/requests/token_expiration_spec.rb +2 -2
- data/spec/routing/clearance_routes_spec.rb +36 -36
- data/spec/support/clearance.rb +1 -1
- data/spec/support/fake_model_without_password_strategy.rb +5 -2
- data/spec/support/generator_spec_helpers.rb +2 -2
- data/spec/support/request_with_remember_token.rb +1 -1
- metadata +5 -3
@@ -1,5 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
+
Person = Class.new(User)
|
4
|
+
|
3
5
|
describe ClearanceMailer do
|
4
6
|
it "is from DO_NOT_REPLY" do
|
5
7
|
user = create(:user)
|
@@ -59,7 +61,6 @@ describe ClearanceMailer do
|
|
59
61
|
context "when using a custom model" do
|
60
62
|
it "contains a link for a custom model" do
|
61
63
|
define_people_routes
|
62
|
-
Person = Class.new(User)
|
63
64
|
person = Person.new(email: "person@example.com", password: "password")
|
64
65
|
|
65
66
|
person.forgot_password!
|
@@ -82,7 +83,7 @@ describe ClearanceMailer do
|
|
82
83
|
resource(
|
83
84
|
:password,
|
84
85
|
controller: "clearance/passwords",
|
85
|
-
only: %i[edit update]
|
86
|
+
only: %i[edit update]
|
86
87
|
)
|
87
88
|
end
|
88
89
|
end
|
data/spec/models/user_spec.rb
CHANGED
@@ -60,7 +60,7 @@ describe User do
|
|
60
60
|
User.authenticate("bad_email@example.com", password)
|
61
61
|
end
|
62
62
|
|
63
|
-
expect(user_does_not_exist_time).
|
63
|
+
expect(user_does_not_exist_time).to be_within(0.01).of(user_exists_time)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "takes the same amount of time to fail authentication regardless of whether user exists" do
|
@@ -74,7 +74,7 @@ describe User do
|
|
74
74
|
User.authenticate("bad_email@example.com", "bad_password")
|
75
75
|
end
|
76
76
|
|
77
|
-
expect(user_does_not_exist_time).
|
77
|
+
expect(user_does_not_exist_time).to be_within(0.01).of(user_exists_time)
|
78
78
|
end
|
79
79
|
|
80
80
|
it "is retrieved via a case-insensitive search" do
|
@@ -16,8 +16,8 @@ describe Clearance::PasswordStrategies::Argon2 do
|
|
16
16
|
it "encrypts with Argon2 using default cost in non test environments" do
|
17
17
|
hasher = stub_argon2_password
|
18
18
|
model_instance = fake_model_with_argon2_strategy
|
19
|
-
allow(Rails).to receive(:env)
|
20
|
-
and_return(ActiveSupport::StringInquirer.new("production"))
|
19
|
+
allow(Rails).to receive(:env)
|
20
|
+
.and_return(ActiveSupport::StringInquirer.new("production"))
|
21
21
|
|
22
22
|
model_instance.password = password
|
23
23
|
|
@@ -69,7 +69,7 @@ describe Clearance::PasswordStrategies::Argon2 do
|
|
69
69
|
|
70
70
|
def fake_model_with_argon2_strategy
|
71
71
|
@fake_model_with_argon2_strategy ||= fake_model_with_password_strategy(
|
72
|
-
Clearance::PasswordStrategies::Argon2
|
72
|
+
Clearance::PasswordStrategies::Argon2
|
73
73
|
)
|
74
74
|
end
|
75
75
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
include FakeModelWithPasswordStrategy
|
3
2
|
|
4
3
|
describe Clearance::PasswordStrategies::BCrypt do
|
4
|
+
include FakeModelWithPasswordStrategy
|
5
5
|
describe "#password=" do
|
6
6
|
it "encrypts the password into encrypted_password" do
|
7
7
|
stub_bcrypt_password
|
@@ -15,14 +15,14 @@ describe Clearance::PasswordStrategies::BCrypt do
|
|
15
15
|
it "encrypts with BCrypt using default cost in non test environments" do
|
16
16
|
stub_bcrypt_password
|
17
17
|
model_instance = fake_model_with_bcrypt_strategy
|
18
|
-
allow(Rails).to receive(:env)
|
19
|
-
and_return(ActiveSupport::StringInquirer.new("production"))
|
18
|
+
allow(Rails).to receive(:env)
|
19
|
+
.and_return(ActiveSupport::StringInquirer.new("production"))
|
20
20
|
|
21
21
|
model_instance.password = password
|
22
22
|
|
23
23
|
expect(BCrypt::Password).to have_received(:create).with(
|
24
24
|
password,
|
25
|
-
cost: ::BCrypt::Engine::DEFAULT_COST
|
25
|
+
cost: ::BCrypt::Engine::DEFAULT_COST
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
include FakeModelWithoutPasswordStrategy
|
3
2
|
|
4
3
|
describe "Password strategy configuration" do
|
4
|
+
include FakeModelWithoutPasswordStrategy
|
5
5
|
describe "when Clearance.configuration.password_strategy is set" do
|
6
6
|
it "includes the value it is set to" do
|
7
7
|
mock_password_strategy = Module.new
|
@@ -39,8 +39,8 @@ describe "Authentication cookies in the response" do
|
|
39
39
|
|
40
40
|
def draw_test_routes
|
41
41
|
Rails.application.routes.draw do
|
42
|
-
get "/private" => "pages#private", as
|
43
|
-
get "/public" => "pages#public", as
|
42
|
+
get "/private" => "pages#private", :as => :private
|
43
|
+
get "/public" => "pages#public", :as => :public
|
44
44
|
resource :session, controller: "clearance/sessions", only: [:create]
|
45
45
|
end
|
46
46
|
end
|
@@ -49,7 +49,7 @@ describe "Authentication cookies in the response" do
|
|
49
49
|
user = create(:user, password: "password")
|
50
50
|
|
51
51
|
post session_path, params: {
|
52
|
-
session: {
|
52
|
+
session: {email: user.email, password: "password"}
|
53
53
|
}
|
54
54
|
end
|
55
55
|
end
|
@@ -12,7 +12,7 @@ describe "Backdoor Middleware" do
|
|
12
12
|
it "removes the `as` param but leaves other parameters unchanged" do
|
13
13
|
user = create(:user)
|
14
14
|
|
15
|
-
get root_path(as: user.to_param, foo:
|
15
|
+
get root_path(as: user.to_param, foo: "bar")
|
16
16
|
|
17
17
|
expect(response.body).to include('{"foo":"bar","controller":"application","action":"show"}')
|
18
18
|
end
|
@@ -13,7 +13,7 @@ describe "Cookie options" do
|
|
13
13
|
get sign_in_path
|
14
14
|
|
15
15
|
post session_path, params: {
|
16
|
-
session: {
|
16
|
+
session: {email: user.email, password: "password"}
|
17
17
|
}
|
18
18
|
end
|
19
19
|
|
@@ -33,7 +33,7 @@ describe "Cookie options" do
|
|
33
33
|
get sign_in_path
|
34
34
|
|
35
35
|
post session_path, params: {
|
36
|
-
session: {
|
36
|
+
session: {email: user.email, password: "password"}
|
37
37
|
}
|
38
38
|
end
|
39
39
|
|
@@ -16,7 +16,7 @@ describe "CSRF Rotation" do
|
|
16
16
|
original_token = csrf_token
|
17
17
|
|
18
18
|
post session_path, params: {
|
19
|
-
authenticity_token: csrf_token, session: {
|
19
|
+
authenticity_token: csrf_token, session: {email: user.email, password: "password"}
|
20
20
|
}
|
21
21
|
|
22
22
|
expect(csrf_token).not_to eq original_token
|
@@ -8,7 +8,7 @@ describe "Password maintenance" do
|
|
8
8
|
put user_password_url(user), params: {
|
9
9
|
user_id: user,
|
10
10
|
token: user.confirmation_token,
|
11
|
-
password_reset: {
|
11
|
+
password_reset: {password: "my_new_password"}
|
12
12
|
}
|
13
13
|
|
14
14
|
expect(response).to redirect_to(Clearance.configuration.redirect_url)
|
@@ -15,7 +15,7 @@ describe "Token expiration" do
|
|
15
15
|
it "should have a remember_token cookie with a future expiration" do
|
16
16
|
expect(first_cookie.expires).to be_between(
|
17
17
|
1.years.from_now - 1.second,
|
18
|
-
1.years.from_now
|
18
|
+
1.years.from_now
|
19
19
|
)
|
20
20
|
end
|
21
21
|
end
|
@@ -53,7 +53,7 @@ describe "Token expiration" do
|
|
53
53
|
get sign_in_path
|
54
54
|
|
55
55
|
post session_path, params: {
|
56
|
-
session: {
|
56
|
+
session: {email: user.email, password: "password"}
|
57
57
|
}
|
58
58
|
end
|
59
59
|
end
|
@@ -1,18 +1,18 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
4
|
-
context
|
5
|
-
it
|
6
|
-
expect(get:
|
7
|
-
expect(get:
|
8
|
-
expect(get:
|
9
|
-
expect(post:
|
10
|
-
expect(post:
|
11
|
-
expect(post:
|
3
|
+
describe "routes for Clearance" do
|
4
|
+
context "routes enabled" do
|
5
|
+
it "draws the default routes" do
|
6
|
+
expect(get: "sign_up").to be_routable
|
7
|
+
expect(get: "sign_in").to be_routable
|
8
|
+
expect(get: "passwords/new").to be_routable
|
9
|
+
expect(post: "session").to be_routable
|
10
|
+
expect(post: "passwords").to be_routable
|
11
|
+
expect(post: "users").to be_routable
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
context
|
15
|
+
context "routes disabled" do
|
16
16
|
around do |example|
|
17
17
|
Clearance.configure { |config| config.routes = false }
|
18
18
|
Rails.application.reload_routes!
|
@@ -21,17 +21,17 @@ describe 'routes for Clearance' do
|
|
21
21
|
Rails.application.reload_routes!
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
25
|
-
expect(get:
|
26
|
-
expect(get:
|
27
|
-
expect(get:
|
28
|
-
expect(post:
|
29
|
-
expect(post:
|
30
|
-
expect(post:
|
24
|
+
it "does not draw any routes" do
|
25
|
+
expect(get: "sign_up").not_to be_routable
|
26
|
+
expect(get: "sign_in").not_to be_routable
|
27
|
+
expect(get: "passwords/new").not_to be_routable
|
28
|
+
expect(post: "session").not_to be_routable
|
29
|
+
expect(post: "passwords").not_to be_routable
|
30
|
+
expect(post: "users").not_to be_routable
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
context
|
34
|
+
context "signup disabled" do
|
35
35
|
around do |example|
|
36
36
|
Clearance.configure { |config| config.allow_sign_up = false }
|
37
37
|
Rails.application.reload_routes!
|
@@ -40,30 +40,30 @@ describe 'routes for Clearance' do
|
|
40
40
|
Rails.application.reload_routes!
|
41
41
|
end
|
42
42
|
|
43
|
-
it
|
44
|
-
expect(get:
|
43
|
+
it "does not route sign_up" do
|
44
|
+
expect(get: "sign_up").not_to be_routable
|
45
45
|
end
|
46
46
|
|
47
|
-
it
|
48
|
-
expect(post:
|
47
|
+
it "does not route to users#create" do
|
48
|
+
expect(post: "users").not_to be_routable
|
49
49
|
end
|
50
50
|
|
51
|
-
it
|
52
|
-
expect(get:
|
51
|
+
it "does not route to users#new" do
|
52
|
+
expect(get: "users/new").not_to be_routable
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
context
|
57
|
-
it
|
58
|
-
expect(get:
|
56
|
+
context "signup enabled" do
|
57
|
+
it "does route sign_up" do
|
58
|
+
expect(get: "sign_up").to be_routable
|
59
59
|
end
|
60
60
|
|
61
|
-
it
|
62
|
-
expect(post:
|
61
|
+
it "does route to users#create" do
|
62
|
+
expect(post: "users").to be_routable
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
context
|
66
|
+
context "password reset disabled" do
|
67
67
|
around do |example|
|
68
68
|
Clearance.configure { |config| config.allow_password_reset = false }
|
69
69
|
Rails.application.reload_routes!
|
@@ -72,24 +72,24 @@ describe 'routes for Clearance' do
|
|
72
72
|
Rails.application.reload_routes!
|
73
73
|
end
|
74
74
|
|
75
|
-
it
|
75
|
+
it "does not route password edit" do
|
76
76
|
user = create(:user)
|
77
77
|
expect(get: "users/#{user.id}/password/edit").not_to be_routable
|
78
78
|
end
|
79
79
|
|
80
|
-
it
|
80
|
+
it "does not route to clearance/passwords#update" do
|
81
81
|
user = create(:user)
|
82
82
|
expect(patch: "/users/#{user.id}/password").not_to be_routable
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
context
|
87
|
-
it
|
86
|
+
context "reset enabled" do
|
87
|
+
it "does route password edit" do
|
88
88
|
user = create(:user)
|
89
89
|
expect(get: "users/#{user.id}/password/edit").to be_routable
|
90
90
|
end
|
91
91
|
|
92
|
-
it
|
92
|
+
it "does route to clearance/passwords#update" do
|
93
93
|
user = create(:user)
|
94
94
|
expect(patch: "/users/#{user.id}/password").to be_routable
|
95
95
|
end
|
data/spec/support/clearance.rb
CHANGED
@@ -5,8 +5,11 @@ module FakeModelWithoutPasswordStrategy
|
|
5
5
|
|
6
6
|
validates_with UniquenessValidator
|
7
7
|
|
8
|
-
def self.before_validation(*)
|
9
|
-
|
8
|
+
def self.before_validation(*)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.before_create(*)
|
12
|
+
end
|
10
13
|
|
11
14
|
include Clearance::User
|
12
15
|
end.new
|
@@ -7,7 +7,7 @@ module RememberTokenHelpers
|
|
7
7
|
cookies[Clearance.configuration.cookie_name] = remember_token
|
8
8
|
end
|
9
9
|
|
10
|
-
env = {
|
10
|
+
env = {clearance: Clearance::Session.new(cookies.request.env)}
|
11
11
|
Rack::Request.new env
|
12
12
|
end
|
13
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clearance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Croak
|
@@ -27,7 +27,7 @@ authors:
|
|
27
27
|
autorequire:
|
28
28
|
bindir: bin
|
29
29
|
cert_chain: []
|
30
|
-
date: 2025-
|
30
|
+
date: 2025-09-26 00:00:00.000000000 Z
|
31
31
|
dependencies:
|
32
32
|
- !ruby/object:Gem::Dependency
|
33
33
|
name: bcrypt
|
@@ -148,8 +148,10 @@ extra_rdoc_files:
|
|
148
148
|
files:
|
149
149
|
- ".erb_lint.yml"
|
150
150
|
- ".github/dependabot.yml"
|
151
|
+
- ".github/workflows/codeql.yml"
|
151
152
|
- ".github/workflows/dynamic-readme.yml"
|
152
153
|
- ".github/workflows/dynamic-security.yml"
|
154
|
+
- ".github/workflows/standardrb.yml"
|
153
155
|
- ".github/workflows/tests.yml"
|
154
156
|
- ".gitignore"
|
155
157
|
- ".yardopts"
|
@@ -323,7 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
323
325
|
- !ruby/object:Gem::Version
|
324
326
|
version: '0'
|
325
327
|
requirements: []
|
326
|
-
rubygems_version: 3.
|
328
|
+
rubygems_version: 3.4.19
|
327
329
|
signing_key:
|
328
330
|
specification_version: 4
|
329
331
|
summary: Rails authentication & authorization with email & password.
|