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