prx_auth 1.7.1 → 1.7.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 +4 -4
- data/.git-blame-ignore-revs +2 -0
- data/.github/workflows/check-project-std.yml +21 -0
- data/Gemfile +1 -1
- data/Guardfile +5 -5
- data/Rakefile +5 -5
- data/lib/prx_auth/resource_map.rb +33 -35
- data/lib/prx_auth/scope_list.rb +26 -26
- data/lib/prx_auth/version.rb +1 -1
- data/lib/prx_auth.rb +3 -3
- data/lib/rack/prx_auth/auth_validator.rb +6 -7
- data/lib/rack/prx_auth/certificate.rb +9 -11
- data/lib/rack/prx_auth/token_data.rb +12 -12
- data/lib/rack/prx_auth.rb +11 -11
- data/prx_auth.gemspec +22 -23
- data/test/prx_auth/resource_map_test.rb +67 -68
- data/test/prx_auth/scope_list_test.rb +53 -55
- data/test/rack/prx_auth/auth_validator_test.rb +49 -50
- data/test/rack/prx_auth/certificate_test.rb +28 -28
- data/test/rack/prx_auth/token_data_test.rb +43 -43
- data/test/rack/prx_auth_test.rb +23 -23
- data/test/test_helper.rb +7 -7
- metadata +25 -16
@@ -1,25 +1,25 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
describe Rack::PrxAuth::Certificate do
|
4
4
|
let(:subject) { Rack::PrxAuth::Certificate.new }
|
5
5
|
let(:certificate) { subject }
|
6
6
|
|
7
|
-
describe
|
8
|
-
it
|
9
|
-
cert = Rack::PrxAuth::Certificate.new(
|
10
|
-
assert cert.cert_location == URI(
|
7
|
+
describe "#initialize" do
|
8
|
+
it "allows setting the location of the certificates" do
|
9
|
+
cert = Rack::PrxAuth::Certificate.new("http://example.com")
|
10
|
+
assert cert.cert_location == URI("http://example.com")
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
13
|
+
it "defaults to DEFAULT_CERT_LOC" do
|
14
14
|
assert certificate.cert_location == Rack::PrxAuth::Certificate::DEFAULT_CERT_LOC
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
describe
|
19
|
-
it
|
18
|
+
describe "#valid?" do
|
19
|
+
it "validates the token with the public key" do
|
20
20
|
token, key = nil, nil
|
21
21
|
certificate.stub(:public_key, :public_key) do
|
22
|
-
JSON::JWT.stub(:decode,
|
22
|
+
JSON::JWT.stub(:decode, proc { |t, k| token, key = t, k }) do
|
23
23
|
certificate.valid?(:token)
|
24
24
|
end
|
25
25
|
end
|
@@ -28,8 +28,8 @@ describe Rack::PrxAuth::Certificate do
|
|
28
28
|
assert key == :public_key
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
JSON::JWT.stub(:decode,
|
31
|
+
it "returns false if verification fails" do
|
32
|
+
JSON::JWT.stub(:decode, proc do |t, k|
|
33
33
|
raise JSON::JWT::VerificationFailed
|
34
34
|
end) do
|
35
35
|
certificate.stub(:public_key, :foo) do
|
@@ -38,7 +38,7 @@ describe Rack::PrxAuth::Certificate do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it "returns true if verification passes" do
|
42
42
|
JSON::JWT.stub(:decode, {}) do
|
43
43
|
certificate.stub(:public_key, :foo) do
|
44
44
|
assert certificate.valid?(:token)
|
@@ -47,8 +47,8 @@ describe Rack::PrxAuth::Certificate do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
describe
|
51
|
-
it
|
50
|
+
describe "#certificate" do
|
51
|
+
it "calls fetch if unprimed" do
|
52
52
|
def certificate.fetch
|
53
53
|
:sigil
|
54
54
|
end
|
@@ -57,16 +57,16 @@ describe Rack::PrxAuth::Certificate do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
describe
|
61
|
-
it
|
60
|
+
describe "#public_key" do
|
61
|
+
it "pulls from the certificate" do
|
62
62
|
certificate.stub(:certificate, Struct.new(:public_key).new(:key)) do
|
63
63
|
assert certificate.send(:public_key) == :key
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
describe
|
69
|
-
it
|
68
|
+
describe "#fetch" do
|
69
|
+
it "pulls from `#cert_location`" do
|
70
70
|
Net::HTTP.stub(:get, ->(x) { "{\"certificates\":{\"asdf\":\"#{x}\"}}" }) do
|
71
71
|
OpenSSL::X509::Certificate.stub(:new, ->(x) { x }) do
|
72
72
|
certificate.stub(:cert_location, "a://fake.url/here") do
|
@@ -76,7 +76,7 @@ describe Rack::PrxAuth::Certificate do
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
it
|
79
|
+
it "sets the expiration value" do
|
80
80
|
Net::HTTP.stub(:get, ->(x) { "{\"certificates\":{\"asdf\":\"#{x}\"}}" }) do
|
81
81
|
OpenSSL::X509::Certificate.stub(:new, ->(_) { Struct.new(:not_after).new(Time.now + 10000) }) do
|
82
82
|
certificate.send :certificate
|
@@ -86,41 +86,41 @@ describe Rack::PrxAuth::Certificate do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
describe
|
89
|
+
describe "#expired?" do
|
90
90
|
let(:stub_cert) { Struct.new(:not_after).new(Time.now + 10000) }
|
91
91
|
before(:each) do
|
92
|
-
certificate.instance_variable_set
|
92
|
+
certificate.instance_variable_set :@certificate, stub_cert
|
93
93
|
end
|
94
94
|
|
95
|
-
it
|
95
|
+
it "is false when the certificate is not expired" do
|
96
96
|
assert !certificate.send(:expired?)
|
97
97
|
end
|
98
98
|
|
99
|
-
it
|
99
|
+
it "is true when the certificate is expired" do
|
100
100
|
stub_cert.not_after = Time.now - 500
|
101
101
|
assert certificate.send(:expired?)
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
describe
|
105
|
+
describe "#needs_refresh?" do
|
106
106
|
def refresh_at=(time)
|
107
|
-
certificate.instance_variable_set
|
107
|
+
certificate.instance_variable_set :@refresh_at, time
|
108
108
|
end
|
109
109
|
|
110
|
-
it
|
110
|
+
it "is true if certificate is expired" do
|
111
111
|
certificate.stub(:expired?, true) do
|
112
112
|
assert certificate.send(:needs_refresh?)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
it
|
116
|
+
it "is true if we are past refresh value" do
|
117
117
|
self.refresh_at = Time.now.to_i - 1000
|
118
118
|
certificate.stub(:expired?, false) do
|
119
119
|
assert certificate.send(:needs_refresh?)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
it
|
123
|
+
it "is false if certificate is not expired and refresh is in the future" do
|
124
124
|
self.refresh_at = Time.now.to_i + 10000
|
125
125
|
certificate.stub(:expired?, false) do
|
126
126
|
assert !certificate.send(:needs_refresh?)
|
@@ -1,99 +1,99 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
describe Rack::PrxAuth::TokenData do
|
4
|
-
it
|
5
|
-
token = Rack::PrxAuth::TokenData.new(
|
4
|
+
it "pulls user_id from sub" do
|
5
|
+
token = Rack::PrxAuth::TokenData.new("sub" => 123)
|
6
6
|
assert token.user_id == 123
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
token = Rack::PrxAuth::TokenData.new(
|
11
|
-
assert token.resources.include?(
|
9
|
+
it "pulls resources from aur" do
|
10
|
+
token = Rack::PrxAuth::TokenData.new("aur" => {"123" => "admin"})
|
11
|
+
assert token.resources.include?("123")
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
15
|
-
token = Rack::PrxAuth::TokenData.new(
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
it "unpacks compressed aur" do
|
15
|
+
token = Rack::PrxAuth::TokenData.new("aur" => {
|
16
|
+
"123" => "member",
|
17
|
+
"$" => {
|
18
|
+
"admin" => [456, 789, 1011]
|
19
19
|
}
|
20
20
|
})
|
21
|
-
assert !token.resources.include?(
|
22
|
-
assert token.resources.include?(
|
23
|
-
assert token.resources.include?(
|
21
|
+
assert !token.resources.include?("$")
|
22
|
+
assert token.resources.include?("789")
|
23
|
+
assert token.resources.include?("123")
|
24
24
|
end
|
25
25
|
|
26
|
-
describe
|
27
|
-
let(:token) { Rack::PrxAuth::TokenData.new(
|
28
|
-
let(:aur) { {
|
26
|
+
describe "#resources" do
|
27
|
+
let(:token) { Rack::PrxAuth::TokenData.new("aur" => aur) }
|
28
|
+
let(:aur) { {"123" => "admin ns1:namespaced", "456" => "member"} }
|
29
29
|
|
30
|
-
it
|
31
|
-
assert token.resources(:admin) == [
|
30
|
+
it "scans for resources by namespace and scope" do
|
31
|
+
assert token.resources(:admin) == ["123"]
|
32
32
|
assert token.resources(:namespaced) == []
|
33
|
-
assert token.resources(:member) == [
|
34
|
-
assert token.resources(:ns1, :namespaced) == [
|
35
|
-
assert token.resources(:ns1, :member) == [
|
33
|
+
assert token.resources(:member) == ["456"]
|
34
|
+
assert token.resources(:ns1, :namespaced) == ["123"]
|
35
|
+
assert token.resources(:ns1, :member) == ["456"]
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
describe
|
40
|
-
let(:token) { Rack::PrxAuth::TokenData.new(
|
41
|
-
let(:scope) {
|
42
|
-
let(:aur) { {
|
39
|
+
describe "#authorized?" do
|
40
|
+
let(:token) { Rack::PrxAuth::TokenData.new("aur" => aur, "scope" => scope) }
|
41
|
+
let(:scope) { "read write purchase sell delete" }
|
42
|
+
let(:aur) { {"123" => "admin ns1:namespaced", "456" => "member"} }
|
43
43
|
|
44
|
-
it
|
45
|
-
assert token.authorized?(123,
|
44
|
+
it "is authorized for scope in aur" do
|
45
|
+
assert token.authorized?(123, "admin")
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
48
|
+
it "is not authorized across aur limits" do
|
49
49
|
assert !token.authorized?(123, :member)
|
50
50
|
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it "does not require a scope" do
|
53
53
|
assert token.authorized?(123)
|
54
54
|
end
|
55
55
|
|
56
|
-
it
|
56
|
+
it "is unauthorized if it hasnt seen the resource" do
|
57
57
|
assert !token.authorized?(789)
|
58
58
|
end
|
59
59
|
|
60
|
-
it
|
60
|
+
it "works for namespaced scopes" do
|
61
61
|
assert token.authorized?(123, :ns1, :namespaced)
|
62
62
|
assert !token.authorized?(123, :namespaced)
|
63
63
|
assert token.authorized?(123, :ns1, :admin)
|
64
64
|
end
|
65
65
|
|
66
|
-
describe
|
67
|
-
let(:aur) { {
|
66
|
+
describe "with wildcard role" do
|
67
|
+
let(:aur) { {"*" => "peek", "123" => "admin", "456" => "member"} }
|
68
68
|
|
69
|
-
it
|
69
|
+
it "applies wildcard tokens to queries with no matching aur" do
|
70
70
|
assert token.authorized?(789, :peek)
|
71
71
|
end
|
72
72
|
|
73
|
-
it
|
73
|
+
it "does not authorize unscoped for wildcard resources" do
|
74
74
|
assert !token.authorized?(789)
|
75
75
|
end
|
76
76
|
|
77
|
-
it
|
78
|
-
assert token.authorized?(
|
79
|
-
assert !token.authorized?(
|
77
|
+
it "allows querying by wildcard resource directly" do
|
78
|
+
assert token.authorized?("*", :peek)
|
79
|
+
assert !token.authorized?("*", :admin)
|
80
80
|
end
|
81
81
|
|
82
|
-
it
|
82
|
+
it "has a shorthand `gobally_authorized?` to query wildcard" do
|
83
83
|
assert token.globally_authorized?(:peek)
|
84
84
|
assert !token.globally_authorized?(:admin)
|
85
85
|
end
|
86
86
|
|
87
|
-
it
|
87
|
+
it "treats global authorizations as additive to other explicit ones" do
|
88
88
|
assert token.authorized?(123, :peek)
|
89
89
|
end
|
90
90
|
|
91
|
-
it
|
91
|
+
it "refuses to run `globally_authorized?` with no scope" do
|
92
92
|
assert_raises ArgumentError do
|
93
93
|
token.globally_authorized?
|
94
94
|
end
|
95
95
|
assert_raises ArgumentError do
|
96
|
-
token.authorized?(
|
96
|
+
token.authorized?("*")
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
data/test/rack/prx_auth_test.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
describe Rack::PrxAuth do
|
4
|
-
let(:app) {
|
4
|
+
let(:app) { proc { |env| env } }
|
5
5
|
let(:prxauth) { Rack::PrxAuth.new(app) }
|
6
|
-
let(:fake_token) {
|
7
|
-
let(:env) { {
|
6
|
+
let(:fake_token) { "afawefawefawefawegstgnsrtiohnlijblublwjnvrtoign" }
|
7
|
+
let(:env) { {"HTTP_AUTHORIZATION" => "Bearer " + fake_token} }
|
8
8
|
let(:iat) { Time.now.to_i }
|
9
9
|
let(:exp) { 3600 }
|
10
|
-
let(:claims) { {
|
10
|
+
let(:claims) { {"sub" => 3, "exp" => exp, "iat" => iat, "token_type" => "bearer", "scope" => nil, "iss" => "id.prx.org"} }
|
11
11
|
|
12
|
-
describe
|
13
|
-
it
|
12
|
+
describe "#call" do
|
13
|
+
it "does nothing if there is no authorization header" do
|
14
14
|
env = {}
|
15
15
|
|
16
16
|
assert prxauth.call(env.clone) == env
|
17
17
|
end
|
18
18
|
|
19
|
-
it
|
20
|
-
claims[
|
19
|
+
it "does nothing if the token is from another issuer" do
|
20
|
+
claims["iss"] = "auth.elsewhere.org"
|
21
21
|
|
22
22
|
JSON::JWT.stub(:decode, claims) do
|
23
23
|
assert prxauth.call(env.clone) == env
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
27
|
+
it "does nothing if token is invalid" do
|
28
28
|
assert prxauth.call(env.clone) == env
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
env = {
|
31
|
+
it "does nothing if the token is nil" do
|
32
|
+
env = {"HTTP_AUTHORIZATION" => "Bearer "}
|
33
33
|
assert prxauth.call(env) == env
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
37
|
-
auth_validator = prxauth.build_auth_validator(
|
36
|
+
it "returns 401 if verification fails" do
|
37
|
+
auth_validator = prxauth.build_auth_validator("sometoken")
|
38
38
|
|
39
39
|
JSON::JWT.stub(:decode, claims) do
|
40
40
|
prxauth.stub(:build_auth_validator, auth_validator) do
|
@@ -45,8 +45,8 @@ describe Rack::PrxAuth do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
49
|
-
auth_validator = prxauth.build_auth_validator(
|
48
|
+
it "returns 401 if access token has expired" do
|
49
|
+
auth_validator = prxauth.build_auth_validator("sometoken")
|
50
50
|
|
51
51
|
JSON::JWT.stub(:decode, claims) do
|
52
52
|
prxauth.stub(:build_auth_validator, auth_validator) do
|
@@ -57,24 +57,24 @@ describe Rack::PrxAuth do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
it
|
61
|
-
auth_validator = prxauth.build_auth_validator(
|
60
|
+
it "attaches claims to request params if verification passes" do
|
61
|
+
auth_validator = prxauth.build_auth_validator("sometoken")
|
62
62
|
|
63
63
|
JSON::JWT.stub(:decode, claims) do
|
64
64
|
prxauth.stub(:build_auth_validator, auth_validator) do
|
65
|
-
prxauth.call(env)[
|
65
|
+
prxauth.call(env)["prx.auth"].tap do |token|
|
66
66
|
assert token.instance_of? Rack::PrxAuth::TokenData
|
67
|
-
assert token.user_id == claims[
|
67
|
+
assert token.user_id == claims["sub"]
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
describe
|
75
|
-
it
|
74
|
+
describe "initialize" do
|
75
|
+
it "takes a certificate location as an option" do
|
76
76
|
loc = nil
|
77
|
-
Rack::PrxAuth::Certificate.stub(:new,
|
77
|
+
Rack::PrxAuth::Certificate.stub(:new, proc { |l| loc = l }) do
|
78
78
|
Rack::PrxAuth.new(app, cert_location: :location)
|
79
79
|
assert loc == :location
|
80
80
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "coveralls"
|
2
2
|
Coveralls.wear!
|
3
3
|
|
4
|
-
$LOAD_PATH.unshift File.expand_path(
|
5
|
-
require
|
6
|
-
require
|
4
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
5
|
+
require "prx_auth"
|
6
|
+
require "rack/prx_auth"
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
8
|
+
require "minitest/autorun"
|
9
|
+
require "minitest/spec"
|
10
|
+
require "minitest/pride"
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prx_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eve Asher
|
8
8
|
- Chris Rhoden
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-05-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -81,6 +81,20 @@ dependencies:
|
|
81
81
|
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: standard
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
99
|
name: rack
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,14 +127,14 @@ dependencies:
|
|
113
127
|
name: json-jwt
|
114
128
|
requirement: !ruby/object:Gem::Requirement
|
115
129
|
requirements:
|
116
|
-
- - "
|
130
|
+
- - ">="
|
117
131
|
- !ruby/object:Gem::Version
|
118
132
|
version: 1.12.0
|
119
133
|
type: :runtime
|
120
134
|
prerelease: false
|
121
135
|
version_requirements: !ruby/object:Gem::Requirement
|
122
136
|
requirements:
|
123
|
-
- - "
|
137
|
+
- - ">="
|
124
138
|
- !ruby/object:Gem::Version
|
125
139
|
version: 1.12.0
|
126
140
|
description: Specific to PRX. Will ignore tokens that were not issued by PRX.
|
@@ -131,6 +145,8 @@ executables: []
|
|
131
145
|
extensions: []
|
132
146
|
extra_rdoc_files: []
|
133
147
|
files:
|
148
|
+
- ".git-blame-ignore-revs"
|
149
|
+
- ".github/workflows/check-project-std.yml"
|
134
150
|
- ".gitignore"
|
135
151
|
- ".travis.yml"
|
136
152
|
- CHANGELOG.md
|
@@ -159,7 +175,7 @@ homepage: https://github.com/PRX/prx_auth
|
|
159
175
|
licenses:
|
160
176
|
- MIT
|
161
177
|
metadata: {}
|
162
|
-
post_install_message:
|
178
|
+
post_install_message:
|
163
179
|
rdoc_options: []
|
164
180
|
require_paths:
|
165
181
|
- lib
|
@@ -174,16 +190,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
190
|
- !ruby/object:Gem::Version
|
175
191
|
version: '0'
|
176
192
|
requirements: []
|
177
|
-
rubygems_version: 3.
|
178
|
-
signing_key:
|
193
|
+
rubygems_version: 3.3.3
|
194
|
+
signing_key:
|
179
195
|
specification_version: 4
|
180
196
|
summary: Utilites for parsing PRX JWTs and Rack middleware that verifies and attaches
|
181
197
|
the token's claims to env.
|
182
|
-
test_files:
|
183
|
-
- test/prx_auth/resource_map_test.rb
|
184
|
-
- test/prx_auth/scope_list_test.rb
|
185
|
-
- test/rack/prx_auth/auth_validator_test.rb
|
186
|
-
- test/rack/prx_auth/certificate_test.rb
|
187
|
-
- test/rack/prx_auth/token_data_test.rb
|
188
|
-
- test/rack/prx_auth_test.rb
|
189
|
-
- test/test_helper.rb
|
198
|
+
test_files: []
|