rails-auth 2.1.2 → 2.2.2
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 +5 -5
- data/.rubocop.yml +14 -1
- data/.travis.yml +8 -5
- data/BUG-BOUNTY.md +3 -3
- data/CHANGES.md +45 -2
- data/CONTRIBUTING.md +11 -10
- data/Gemfile +6 -5
- data/Guardfile +2 -0
- data/Rakefile +3 -1
- data/lib/rails/auth/acl.rb +4 -0
- data/lib/rails/auth/acl/matchers/allow_all.rb +3 -0
- data/lib/rails/auth/acl/middleware.rb +3 -0
- data/lib/rails/auth/acl/resource.rb +7 -5
- data/lib/rails/auth/config_builder.rb +5 -1
- data/lib/rails/auth/controller_methods.rb +4 -0
- data/lib/rails/auth/credentials.rb +3 -1
- data/lib/rails/auth/credentials/injector_middleware.rb +6 -2
- data/lib/rails/auth/env.rb +4 -3
- data/lib/rails/auth/error_page/debug_middleware.rb +1 -1
- data/lib/rails/auth/error_page/middleware.rb +3 -0
- data/lib/rails/auth/exceptions.rb +2 -0
- data/lib/rails/auth/helpers.rb +3 -1
- data/lib/rails/auth/installed_constraint.rb +2 -0
- data/lib/rails/auth/monitor/middleware.rb +2 -0
- data/lib/rails/auth/rack.rb +1 -0
- data/lib/rails/auth/rspec.rb +2 -0
- data/lib/rails/auth/rspec/helper_methods.rb +6 -5
- data/lib/rails/auth/rspec/matchers/acl_matchers.rb +4 -2
- data/lib/rails/auth/version.rb +1 -1
- data/lib/rails/auth/x509/certificate.rb +35 -5
- data/lib/rails/auth/x509/filter/java.rb +4 -12
- data/lib/rails/auth/x509/filter/pem.rb +10 -1
- data/lib/rails/auth/x509/matcher.rb +2 -0
- data/lib/rails/auth/x509/middleware.rb +11 -9
- data/lib/rails/auth/x509/subject_alt_name_extension.rb +29 -0
- data/rails-auth.gemspec +5 -4
- data/spec/rails/auth/acl/matchers/allow_all_spec.rb +2 -0
- data/spec/rails/auth/acl/middleware_spec.rb +2 -0
- data/spec/rails/auth/acl/resource_spec.rb +2 -0
- data/spec/rails/auth/acl_spec.rb +2 -0
- data/spec/rails/auth/controller_methods_spec.rb +2 -0
- data/spec/rails/auth/credentials/injector_middleware_spec.rb +15 -0
- data/spec/rails/auth/credentials_spec.rb +2 -0
- data/spec/rails/auth/env_spec.rb +2 -0
- data/spec/rails/auth/error_page/debug_middleware_spec.rb +2 -0
- data/spec/rails/auth/error_page/middleware_spec.rb +2 -0
- data/spec/rails/auth/monitor/middleware_spec.rb +2 -0
- data/spec/rails/auth/rspec/helper_methods_spec.rb +2 -0
- data/spec/rails/auth/rspec/matchers/acl_matchers_spec.rb +12 -1
- data/spec/rails/auth/x509/certificate_spec.rb +103 -20
- data/spec/rails/auth/x509/matcher_spec.rb +2 -0
- data/spec/rails/auth/x509/middleware_spec.rb +13 -2
- data/spec/rails/auth/x509/subject_alt_name_extension_spec.rb +39 -0
- data/spec/rails/auth_spec.rb +2 -0
- data/spec/spec_helper.rb +5 -3
- data/spec/support/claims_matcher.rb +2 -0
- data/spec/support/create_certs.rb +57 -2
- metadata +14 -7
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "logger"
|
2
4
|
|
3
5
|
RSpec.describe Rails::Auth::X509::Middleware do
|
@@ -33,6 +35,13 @@ RSpec.describe Rails::Auth::X509::Middleware do
|
|
33
35
|
_response, env = middleware.call(request.merge(example_key => bad_cert_pem))
|
34
36
|
expect(Rails::Auth.credentials(env)).to be_empty
|
35
37
|
end
|
38
|
+
|
39
|
+
it "normalizes abnormal whitespace" do
|
40
|
+
_response, env = middleware.call(request.merge(example_key => valid_cert_pem.tr("\n", "\t")))
|
41
|
+
|
42
|
+
credential = Rails::Auth.credentials(env).fetch("x509")
|
43
|
+
expect(credential).to be_a Rails::Auth::X509::Certificate
|
44
|
+
end
|
36
45
|
end
|
37
46
|
|
38
47
|
# :nocov:
|
@@ -42,10 +51,12 @@ RSpec.describe Rails::Auth::X509::Middleware do
|
|
42
51
|
|
43
52
|
let(:java_cert) do
|
44
53
|
ruby_cert = OpenSSL::X509::Certificate.new(valid_cert_pem)
|
45
|
-
Java::
|
54
|
+
input_stream = Java::JavaIO::ByteArrayInputStream.new(ruby_cert.to_der.to_java_bytes)
|
55
|
+
java_cert_klass = Java::JavaSecurityCert::CertificateFactory.getInstance("X.509")
|
56
|
+
java_cert_klass.generateCertificate(input_stream)
|
46
57
|
end
|
47
58
|
|
48
|
-
it "extracts Rails::Auth::Credential::X509 from a
|
59
|
+
it "extracts Rails::Auth::Credential::X509 from a java.security.cert.Certificate" do
|
49
60
|
skip "JRuby only" unless defined?(JRUBY_VERSION)
|
50
61
|
|
51
62
|
_response, env = middleware.call(request.merge(example_key => [java_cert]))
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Rails::Auth::X509::SubjectAltNameExtension do
|
4
|
+
let(:example_cert) { OpenSSL::X509::Certificate.new(cert_path("valid.crt").read) }
|
5
|
+
let(:example_cert_with_extension) { OpenSSL::X509::Certificate.new(cert_path("valid_with_ext.crt").read) }
|
6
|
+
let(:extension_for_cert) { described_class.new(example_cert) }
|
7
|
+
let(:extension_for_cert_with_san) { described_class.new(example_cert_with_extension) }
|
8
|
+
let(:example_dns_names) { %w[example.com exemplar.com somethingelse.com] }
|
9
|
+
let(:example_ips) { %w[0.0.0.0 127.0.0.1 192.168.1.1] }
|
10
|
+
let(:example_uris) { %w[spiffe://example.com/exemplar https://www.example.com/page1 https://www.example.com/page2] }
|
11
|
+
|
12
|
+
describe "for cert without extensions" do
|
13
|
+
it "returns no DNS names" do
|
14
|
+
expect(extension_for_cert.dns_names).to be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns no IPs" do
|
18
|
+
expect(extension_for_cert.ips).to be_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns no URIs" do
|
22
|
+
expect(extension_for_cert.uris).to be_empty
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "for cert with extensions" do
|
27
|
+
it "knows its DNS names" do
|
28
|
+
expect(extension_for_cert_with_san.dns_names).to eq example_dns_names
|
29
|
+
end
|
30
|
+
|
31
|
+
it "knows its IPs" do
|
32
|
+
expect(extension_for_cert_with_san.ips).to eq example_ips
|
33
|
+
end
|
34
|
+
|
35
|
+
it "knows its URIs" do
|
36
|
+
expect(extension_for_cert_with_san.uris).to eq example_uris
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/rails/auth_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "coveralls"
|
2
4
|
Coveralls.wear!
|
3
5
|
|
4
|
-
$LOAD_PATH.unshift File.expand_path("
|
6
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
5
7
|
require "rails/auth"
|
6
8
|
require "rails/auth/rspec"
|
7
9
|
require "support/create_certs"
|
@@ -11,11 +13,11 @@ require "pathname"
|
|
11
13
|
RSpec.configure(&:disable_monkey_patching!)
|
12
14
|
|
13
15
|
def cert_path(name)
|
14
|
-
Pathname.new(File.expand_path("
|
16
|
+
Pathname.new(File.expand_path("../tmp/certs", __dir__)).join(name)
|
15
17
|
end
|
16
18
|
|
17
19
|
def fixture_path(*args)
|
18
|
-
Pathname.new(File.expand_path("
|
20
|
+
Pathname.new(File.expand_path("fixtures", __dir__)).join(*args)
|
19
21
|
end
|
20
22
|
|
21
23
|
def env_for(method, path, host = "127.0.0.1")
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "certificate_authority"
|
2
4
|
require "fileutils"
|
3
5
|
|
4
|
-
cert_path = File.expand_path("
|
6
|
+
cert_path = File.expand_path("../../tmp/certs", __dir__)
|
5
7
|
FileUtils.mkdir_p(cert_path)
|
6
8
|
|
7
9
|
#
|
@@ -15,7 +17,7 @@ ca.serial_number.number = 1
|
|
15
17
|
ca.key_material.generate_key
|
16
18
|
ca.signing_entity = true
|
17
19
|
|
18
|
-
ca.sign! "extensions" => { "keyUsage" => { "usage" => %w
|
20
|
+
ca.sign! "extensions" => { "keyUsage" => { "usage" => %w[critical keyCertSign] } }
|
19
21
|
|
20
22
|
ca_cert_path = File.join(cert_path, "ca.crt")
|
21
23
|
ca_key_path = File.join(cert_path, "ca.key")
|
@@ -41,6 +43,59 @@ valid_key_path = File.join(cert_path, "valid.key")
|
|
41
43
|
File.write valid_cert_path, valid_cert.to_pem
|
42
44
|
File.write valid_key_path, valid_cert.key_material.private_key.to_pem
|
43
45
|
|
46
|
+
#
|
47
|
+
# Valid client certificate with extensions
|
48
|
+
#
|
49
|
+
|
50
|
+
valid_cert_with_ext = CertificateAuthority::Certificate.new
|
51
|
+
valid_cert_with_ext.subject.common_name = "127.0.0.1"
|
52
|
+
valid_cert_with_ext.subject.organizational_unit = "ponycopter"
|
53
|
+
valid_cert_with_ext.serial_number.number = 3
|
54
|
+
valid_cert_with_ext.key_material.generate_key
|
55
|
+
signing_profile = {
|
56
|
+
"extensions" => {
|
57
|
+
"basicConstraints" => {
|
58
|
+
"ca" => false
|
59
|
+
},
|
60
|
+
"crlDistributionPoints" => {
|
61
|
+
"uri" => "http://notme.com/other.crl"
|
62
|
+
},
|
63
|
+
"subjectKeyIdentifier" => {},
|
64
|
+
"authorityKeyIdentifier" => {},
|
65
|
+
"authorityInfoAccess" => {
|
66
|
+
"ocsp" => %w[http://youFillThisOut/ocsp/]
|
67
|
+
},
|
68
|
+
"keyUsage" => {
|
69
|
+
"usage" => %w[digitalSignature keyEncipherment dataEncipherment]
|
70
|
+
},
|
71
|
+
"extendedKeyUsage" => {
|
72
|
+
"usage" => %w[serverAuth clientAuth]
|
73
|
+
},
|
74
|
+
"subjectAltName" => {
|
75
|
+
"uris" => %w[spiffe://example.com/exemplar https://www.example.com/page1 https://www.example.com/page2],
|
76
|
+
"ips" => %w[0.0.0.0 127.0.0.1 192.168.1.1],
|
77
|
+
"dns_names" => %w[example.com exemplar.com somethingelse.com]
|
78
|
+
},
|
79
|
+
"certificatePolicies" => {
|
80
|
+
"policy_identifier" => "1.3.5.8",
|
81
|
+
"cps_uris" => %w[http://my.host.name/ http://my.your.name/],
|
82
|
+
"user_notice" => {
|
83
|
+
"explicit_text" => "Explicit Text Here",
|
84
|
+
"organization" => "Organization name",
|
85
|
+
"notice_numbers" => "1,2,3,4"
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
valid_cert_with_ext.parent = ca
|
91
|
+
valid_cert_with_ext.sign!(signing_profile)
|
92
|
+
|
93
|
+
valid_cert_with_ext_path = File.join(cert_path, "valid_with_ext.crt")
|
94
|
+
valid_key_with_ext_path = File.join(cert_path, "valid_with_ext.key")
|
95
|
+
|
96
|
+
File.write valid_cert_with_ext_path, valid_cert_with_ext.to_pem
|
97
|
+
File.write valid_key_with_ext_path, valid_cert_with_ext.key_material.private_key.to_pem
|
98
|
+
|
44
99
|
#
|
45
100
|
# Create evil MitM self-signed certificate
|
46
101
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -28,16 +28,22 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.10'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '3'
|
34
37
|
type: :development
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">="
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '1.10'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '3'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: rake
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +108,7 @@ files:
|
|
102
108
|
- lib/rails/auth/x509/filter/pem.rb
|
103
109
|
- lib/rails/auth/x509/matcher.rb
|
104
110
|
- lib/rails/auth/x509/middleware.rb
|
111
|
+
- lib/rails/auth/x509/subject_alt_name_extension.rb
|
105
112
|
- rails-auth.gemspec
|
106
113
|
- spec/fixtures/example_acl.yml
|
107
114
|
- spec/rails/auth/acl/matchers/allow_all_spec.rb
|
@@ -120,6 +127,7 @@ files:
|
|
120
127
|
- spec/rails/auth/x509/certificate_spec.rb
|
121
128
|
- spec/rails/auth/x509/matcher_spec.rb
|
122
129
|
- spec/rails/auth/x509/middleware_spec.rb
|
130
|
+
- spec/rails/auth/x509/subject_alt_name_extension_spec.rb
|
123
131
|
- spec/rails/auth_spec.rb
|
124
132
|
- spec/spec_helper.rb
|
125
133
|
- spec/support/claims_matcher.rb
|
@@ -137,15 +145,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
145
|
requirements:
|
138
146
|
- - ">="
|
139
147
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.
|
148
|
+
version: 2.3.0
|
141
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
150
|
requirements:
|
143
151
|
- - ">="
|
144
152
|
- !ruby/object:Gem::Version
|
145
153
|
version: '0'
|
146
154
|
requirements: []
|
147
|
-
|
148
|
-
rubygems_version: 2.6.8
|
155
|
+
rubygems_version: 3.0.3
|
149
156
|
signing_key:
|
150
157
|
specification_version: 4
|
151
158
|
summary: Modular resource-oriented authentication and authorization for Rails/Rack
|