rack-prx_auth 0.3.0 → 1.0.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/lib/prx_auth.rb +7 -0
- data/lib/prx_auth/resource_map.rb +49 -0
- data/lib/prx_auth/scope_list.rb +58 -0
- data/lib/rack/prx_auth.rb +1 -0
- data/lib/rack/prx_auth/token_data.rb +16 -29
- data/lib/rack/prx_auth/version.rb +1 -1
- data/test/prx_auth/resource_map_test.rb +98 -0
- data/test/prx_auth/scope_list_test.rb +44 -0
- data/test/rack/prx_auth/certificate_test.rb +15 -15
- data/test/rack/prx_auth/token_data_test.rb +26 -31
- data/test/rack/prx_auth_test.rb +15 -16
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 007badaca2bcd0d872e5bb23d18ba81098707f5417444688917a54444cf3bbcf
|
4
|
+
data.tar.gz: 799e16711cd95cba80a48608bad0d936da2bf26bcad96b713e8180a79c69650d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f276c65f9164b4c7b7fbe3fce4e09e10ea6d8e2e8e264cfa7110887b0b92da8e6f07602b822abf25687fadb60f68706f96834cbdd01a0eea64ab18721846366f
|
7
|
+
data.tar.gz: 2d3be4be1f0e42c5cd7d31e96b31e878d81f1ca914ad677351ff53e58d161cbdded223285211ee2d9b7b733c51b3dc3c1bb47cc508498928eccd66305bb97ee0
|
data/lib/prx_auth.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module PrxAuth
|
2
|
+
class ResourceMap
|
3
|
+
WILDCARD_KEY = '*'
|
4
|
+
|
5
|
+
def initialize(mapped_values)
|
6
|
+
input = mapped_values.clone
|
7
|
+
@wildcard = ScopeList.new(input.delete(WILDCARD_KEY)||'')
|
8
|
+
@map = Hash[input.map do |(key, values)|
|
9
|
+
[key, ScopeList.new(values)]
|
10
|
+
end]
|
11
|
+
end
|
12
|
+
|
13
|
+
def contains?(resource, namespace=nil, scope=nil)
|
14
|
+
resource = resource.to_s
|
15
|
+
|
16
|
+
if resource == WILDCARD_KEY
|
17
|
+
raise ArgumentError if namespace.nil?
|
18
|
+
|
19
|
+
@wildcard.contains?(namespace, scope)
|
20
|
+
else
|
21
|
+
mapped_resource = @map[resource]
|
22
|
+
|
23
|
+
if mapped_resource && !namespace.nil?
|
24
|
+
mapped_resource.contains?(namespace, scope) || @wildcard.contains?(namespace, scope)
|
25
|
+
elsif !namespace.nil?
|
26
|
+
@wildcard.contains?(namespace, scope)
|
27
|
+
else
|
28
|
+
!!mapped_resource
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def freeze
|
34
|
+
@map.freeze
|
35
|
+
@wildcard.freeze
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def resources(namespace=nil, scope=nil)
|
40
|
+
if namespace.nil?
|
41
|
+
@map.keys
|
42
|
+
else
|
43
|
+
@map.select do |name, list|
|
44
|
+
list.contains?(namespace, scope)
|
45
|
+
end.map(&:first)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module PrxAuth
|
2
|
+
class ScopeList
|
3
|
+
SCOPE_SEPARATOR = ' '
|
4
|
+
NAMESPACE_SEPARATOR = ':'
|
5
|
+
NO_NAMESPACE = :_
|
6
|
+
|
7
|
+
def initialize(list)
|
8
|
+
@string = list
|
9
|
+
end
|
10
|
+
|
11
|
+
def contains?(namespace, scope=nil)
|
12
|
+
scope, namespace = namespace, NO_NAMESPACE if scope.nil?
|
13
|
+
|
14
|
+
if namespace == NO_NAMESPACE
|
15
|
+
map[namespace].include?(symbolize(scope))
|
16
|
+
else
|
17
|
+
symbolized_scope = symbolize(scope)
|
18
|
+
map[symbolize(namespace)].include?(symbolized_scope) || map[NO_NAMESPACE].include?(symbolized_scope)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def freeze
|
23
|
+
@string.freeze
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def map
|
30
|
+
@parsed_map ||= empty_map.tap do |map|
|
31
|
+
@string.split(SCOPE_SEPARATOR).each do |value|
|
32
|
+
next if value.length < 1
|
33
|
+
|
34
|
+
parts = value.split(NAMESPACE_SEPARATOR, 2)
|
35
|
+
if parts.length == 2
|
36
|
+
map[symbolize(parts[0])] << symbolize(parts[1])
|
37
|
+
else
|
38
|
+
map[NO_NAMESPACE] << symbolize(parts[0])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def empty_map
|
45
|
+
@empty_map ||= Hash.new do |hash, key|
|
46
|
+
hash[key] = []
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def symbolize(value)
|
51
|
+
case value
|
52
|
+
when Symbol then value
|
53
|
+
when String then value.downcase.gsub('-', '_').intern
|
54
|
+
else symbolize value.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/rack/prx_auth.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
+
require 'prx_auth/resource_map'
|
2
|
+
|
1
3
|
module Rack
|
2
4
|
class PrxAuth
|
3
5
|
class TokenData
|
4
|
-
|
5
|
-
|
6
|
-
attr_reader :attributes, :authorized_resources, :scopes
|
6
|
+
attr_reader :scopes
|
7
7
|
|
8
8
|
def initialize(attrs = {})
|
9
9
|
@attributes = attrs
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@authorized_resources = {}.freeze
|
14
|
-
end
|
10
|
+
|
11
|
+
@authorized_resources = ::PrxAuth::ResourceMap.new(unpack_aur(attrs['aur'])).freeze
|
12
|
+
|
15
13
|
if attrs['scope']
|
16
14
|
@scopes = attrs['scope'].split(' ').freeze
|
17
15
|
else
|
@@ -19,35 +17,27 @@ module Rack
|
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
20
|
+
def resources(namespace=nil, scope=nil)
|
21
|
+
@authorized_resources.resources(namespace, scope)
|
22
|
+
end
|
23
|
+
|
22
24
|
def user_id
|
23
25
|
@attributes['sub']
|
24
26
|
end
|
25
27
|
|
26
|
-
def authorized?(resource, scope=nil)
|
27
|
-
|
28
|
-
globally_authorized?(scope)
|
29
|
-
elsif scope.nil?
|
30
|
-
authorized_for_resource?(resource, scope)
|
31
|
-
else
|
32
|
-
authorized_for_resource?(resource, scope) || globally_authorized?(scope)
|
33
|
-
end
|
28
|
+
def authorized?(resource, namespace=nil, scope=nil)
|
29
|
+
@authorized_resources.contains?(resource, namespace, scope)
|
34
30
|
end
|
35
31
|
|
36
|
-
def globally_authorized?(scope)
|
37
|
-
|
38
|
-
|
39
|
-
authorized_for_resource?(WILDCARD_RESOURCE_NAME, scope)
|
32
|
+
def globally_authorized?(namespace, scope=nil)
|
33
|
+
authorized?(::PrxAuth::ResourceMap::WILDCARD_KEY, namespace, scope)
|
40
34
|
end
|
41
35
|
|
42
36
|
private
|
43
37
|
|
44
|
-
def authorized_for_resource?(resource, scope=nil)
|
45
|
-
if auth = authorized_resources[resource.to_s]
|
46
|
-
scope.nil? || (scopes + auth.split(' ')).include?(scope.to_s)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
38
|
def unpack_aur(aur)
|
39
|
+
return {} if aur.nil?
|
40
|
+
|
51
41
|
aur.clone.tap do |result|
|
52
42
|
unless result['$'].nil?
|
53
43
|
result.delete('$').each do |role, resources|
|
@@ -56,9 +46,6 @@ module Rack
|
|
56
46
|
end
|
57
47
|
end
|
58
48
|
end
|
59
|
-
if result[WILDCARD_RESOURCE_NAME].nil? && result['0']
|
60
|
-
result[WILDCARD_RESOURCE_NAME] = result.delete('0')
|
61
|
-
end
|
62
49
|
end
|
63
50
|
end
|
64
51
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe PrxAuth::ResourceMap do
|
4
|
+
let(:map) { PrxAuth::ResourceMap.new(input) }
|
5
|
+
let(:input) { {'123' => 'admin one two three ns1:namespaced', '456' => 'member four five six' } }
|
6
|
+
|
7
|
+
describe '#authorized?' do
|
8
|
+
it 'contains scopes in list' do
|
9
|
+
assert map.contains?(123, :admin)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'does not include across aur limits' do
|
13
|
+
assert !map.contains?(123, :member)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'does not require a scope' do
|
17
|
+
assert map.contains?(123)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'does not match if it hasnt seen the resource' do
|
21
|
+
assert !map.contains?(789)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'works with namespaced scopes' do
|
25
|
+
assert map.contains?(123, :ns1, :namespaced)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'with wildcard resource' do
|
29
|
+
let(:input) do
|
30
|
+
{
|
31
|
+
'*' => 'peek',
|
32
|
+
'123' => 'admin one two three',
|
33
|
+
'456' => 'member four five six'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'applies wildcard lists to queries with no matching value' do
|
38
|
+
assert map.contains?(789, :peek)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'does not scan unscoped for wildcard resources' do
|
42
|
+
assert !map.contains?(789)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'allows querying by wildcard resource directly' do
|
46
|
+
assert map.contains?('*', :peek)
|
47
|
+
assert !map.contains?('*', :admin)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'treats wildcard lists as additive to other explicit ones' do
|
51
|
+
assert map.contains?(123, :peek)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'refuses to run against wildcard with no scope' do
|
55
|
+
assert_raises ArgumentError do
|
56
|
+
map.contains?('*')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#resources' do
|
63
|
+
let (:input) do
|
64
|
+
{
|
65
|
+
'*' => 'read wildcard',
|
66
|
+
'123' => 'read write buy',
|
67
|
+
'456' => 'read ns1:buy'
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
let (:resources) { map.resources }
|
72
|
+
|
73
|
+
it 'returns resource ids' do
|
74
|
+
assert resources.include?('123')
|
75
|
+
assert resources.include?('456')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'excludes wildcard values' do
|
79
|
+
assert !resources.include?('*')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'filters for scope' do
|
83
|
+
resources = map.resources(:write)
|
84
|
+
assert resources.include?('123')
|
85
|
+
assert !resources.include?('456')
|
86
|
+
assert !resources.include?('*')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'works with namespaces' do
|
90
|
+
resources = map.resources(:ns1, :buy)
|
91
|
+
assert resources.include?('123')
|
92
|
+
assert resources.include?('456')
|
93
|
+
|
94
|
+
resources = map.resources(:buy)
|
95
|
+
assert !resources.include?('456')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe PrxAuth::ScopeList do
|
4
|
+
let (:scopes) { 'read write sell top-up' }
|
5
|
+
let (:list) { PrxAuth::ScopeList.new(scopes) }
|
6
|
+
|
7
|
+
it 'looks up successfully for a given scope' do
|
8
|
+
assert list.contains?('write')
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'scans for symbols' do
|
12
|
+
assert list.contains?(:read)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'handles hyphen to underscore conversions' do
|
16
|
+
assert list.contains?(:top_up)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'fails for contents not in the list' do
|
20
|
+
assert !list.contains?(:buy)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'with namespace' do
|
24
|
+
let (:scopes) { 'ns1:hello ns2:goodbye aloha 1:23' }
|
25
|
+
|
26
|
+
it 'works for namespaced lookups' do
|
27
|
+
assert list.contains?(:ns1, :hello)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'fails when the wrong namespace is passed' do
|
31
|
+
assert !list.contains?(:ns1, :goodbye)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'looks up global scopes when namespaced fails' do
|
35
|
+
assert list.contains?(:ns1, :aloha)
|
36
|
+
assert list.contains?(:ns3, :aloha)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'works with non-symbol namespaces' do
|
40
|
+
assert list.contains?(1, 23)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -7,11 +7,11 @@ describe Rack::PrxAuth::Certificate do
|
|
7
7
|
describe '#initialize' do
|
8
8
|
it 'allows setting the location of the certificates' do
|
9
9
|
cert = Rack::PrxAuth::Certificate.new('http://example.com')
|
10
|
-
cert.cert_location
|
10
|
+
assert cert.cert_location == URI('http://example.com')
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'defaults to DEFAULT_CERT_LOC' do
|
14
|
-
certificate.cert_location
|
14
|
+
assert certificate.cert_location == Rack::PrxAuth::Certificate::DEFAULT_CERT_LOC
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -24,8 +24,8 @@ describe Rack::PrxAuth::Certificate do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
token
|
28
|
-
key
|
27
|
+
assert token == :token
|
28
|
+
assert key == :public_key
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'returns false if verification fails' do
|
@@ -33,7 +33,7 @@ describe Rack::PrxAuth::Certificate do
|
|
33
33
|
raise JSON::JWT::VerificationFailed
|
34
34
|
end) do
|
35
35
|
certificate.stub(:public_key, :foo) do
|
36
|
-
certificate.
|
36
|
+
assert !certificate.valid?(:token)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -41,7 +41,7 @@ describe Rack::PrxAuth::Certificate do
|
|
41
41
|
it 'returns true if verification passes' do
|
42
42
|
JSON::JWT.stub(:decode, {}) do
|
43
43
|
certificate.stub(:public_key, :foo) do
|
44
|
-
certificate.
|
44
|
+
assert certificate.valid?(:token)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -53,14 +53,14 @@ describe Rack::PrxAuth::Certificate do
|
|
53
53
|
:sigil
|
54
54
|
end
|
55
55
|
|
56
|
-
certificate.send(:certificate)
|
56
|
+
assert certificate.send(:certificate) == :sigil
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
describe '#public_key' do
|
61
61
|
it 'pulls from the certificate' do
|
62
62
|
certificate.stub(:certificate, Struct.new(:public_key).new(:key)) do
|
63
|
-
certificate.send(:public_key)
|
63
|
+
assert certificate.send(:public_key) == :key
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -70,7 +70,7 @@ describe Rack::PrxAuth::Certificate 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
|
73
|
-
certificate.send(:fetch)
|
73
|
+
assert certificate.send(:fetch) == "a://fake.url/here"
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -80,7 +80,7 @@ describe Rack::PrxAuth::Certificate 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
|
83
|
-
certificate.
|
83
|
+
assert !certificate.send(:needs_refresh?)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -93,12 +93,12 @@ describe Rack::PrxAuth::Certificate do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'is false when the certificate is not expired' do
|
96
|
-
certificate.
|
96
|
+
assert !certificate.send(:expired?)
|
97
97
|
end
|
98
98
|
|
99
99
|
it 'is true when the certificate is expired' do
|
100
100
|
stub_cert.not_after = Time.now - 500
|
101
|
-
certificate.
|
101
|
+
assert certificate.send(:expired?)
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
@@ -109,21 +109,21 @@ describe Rack::PrxAuth::Certificate do
|
|
109
109
|
|
110
110
|
it 'is true if certificate is expired' do
|
111
111
|
certificate.stub(:expired?, true) do
|
112
|
-
certificate.
|
112
|
+
assert certificate.send(:needs_refresh?)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
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
|
-
certificate.
|
119
|
+
assert certificate.send(:needs_refresh?)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
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
|
-
certificate.
|
126
|
+
assert !certificate.send(:needs_refresh?)
|
127
127
|
end
|
128
128
|
end
|
129
129
|
end
|
@@ -6,36 +6,45 @@ describe Rack::PrxAuth::TokenData do
|
|
6
6
|
assert token.user_id == 123
|
7
7
|
end
|
8
8
|
|
9
|
-
it 'pulls
|
9
|
+
it 'pulls resources from aur' do
|
10
10
|
token = Rack::PrxAuth::TokenData.new('aur' => {'123' => 'admin'})
|
11
|
-
assert token.
|
11
|
+
assert token.resources.include?('123')
|
12
12
|
end
|
13
13
|
|
14
|
-
it 'unpacks compressed aur
|
14
|
+
it 'unpacks compressed aur' do
|
15
15
|
token = Rack::PrxAuth::TokenData.new('aur' => {
|
16
16
|
'123' => 'member',
|
17
17
|
'$' => {
|
18
18
|
'admin' => [456, 789, 1011]
|
19
19
|
}
|
20
20
|
})
|
21
|
-
assert token.
|
22
|
-
assert token.
|
23
|
-
assert token.
|
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
|
24
37
|
end
|
25
38
|
|
26
39
|
describe '#authorized?' do
|
27
40
|
let(:token) { Rack::PrxAuth::TokenData.new('aur' => aur, 'scope' => scope) }
|
28
41
|
let(:scope) { 'read write purchase sell delete' }
|
29
|
-
let(:aur) { {'123' => 'admin', '456' => 'member' } }
|
42
|
+
let(:aur) { {'123' => 'admin ns1:namespaced', '456' => 'member' } }
|
30
43
|
|
31
44
|
it 'is authorized for scope in aur' do
|
32
45
|
assert token.authorized?(123, 'admin')
|
33
46
|
end
|
34
47
|
|
35
|
-
it 'is authorized for scope in scopes' do
|
36
|
-
assert token.authorized?(456, :delete)
|
37
|
-
end
|
38
|
-
|
39
48
|
it 'is not authorized across aur limits' do
|
40
49
|
assert !token.authorized?(123, :member)
|
41
50
|
end
|
@@ -48,6 +57,12 @@ describe Rack::PrxAuth::TokenData do
|
|
48
57
|
assert !token.authorized?(789)
|
49
58
|
end
|
50
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
|
+
|
51
66
|
describe 'with wildcard role' do
|
52
67
|
let(:aur) { {'*' => 'peek', '123' => 'admin', '456' => 'member' } }
|
53
68
|
|
@@ -82,25 +97,5 @@ describe Rack::PrxAuth::TokenData do
|
|
82
97
|
end
|
83
98
|
end
|
84
99
|
end
|
85
|
-
|
86
|
-
describe 'wildcard fallback handling' do
|
87
|
-
|
88
|
-
describe 'with no primary wildcard present' do
|
89
|
-
let(:aur) { {'0' => 'peek', '123' => 'admin', '456' => 'member' } }
|
90
|
-
|
91
|
-
it 'applies fallback as a wildcard' do
|
92
|
-
assert token.authorized?(789, :peek)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
describe 'with primary wildcard present' do
|
97
|
-
let(:aur) { {'*' => 'cook', '0' => 'peek', '123' => 'admin', '456' => 'member' } }
|
98
|
-
|
99
|
-
it 'does not apply the fallback as a wildcard' do
|
100
|
-
assert token.authorized?(789, :cook)
|
101
|
-
assert !token.authorized?(789, :peek)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
100
|
end
|
106
101
|
end
|
data/test/rack/prx_auth_test.rb
CHANGED
@@ -11,30 +11,30 @@ describe Rack::PrxAuth do
|
|
11
11
|
it 'does nothing if there is no authorization header' do
|
12
12
|
env = {}
|
13
13
|
|
14
|
-
prxauth.call(env.clone)
|
14
|
+
assert prxauth.call(env.clone) == env
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'does nothing if the token is from another issuer' do
|
18
18
|
claims['iss'] = 'auth.elsewhere.org'
|
19
19
|
|
20
20
|
JSON::JWT.stub(:decode, claims) do
|
21
|
-
prxauth.call(env.clone)
|
21
|
+
assert prxauth.call(env.clone) == env
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'does nothing if token is invalid' do
|
26
|
-
prxauth.call(env.clone)
|
26
|
+
assert prxauth.call(env.clone) == env
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'does nothing if the token is nil' do
|
30
|
-
env = {"HTTP_AUTHORIZATION"=>"Bearer "}
|
31
|
-
prxauth.call(env)
|
30
|
+
env = { "HTTP_AUTHORIZATION" => "Bearer "}
|
31
|
+
assert prxauth.call(env) == env
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'returns 401 if verification fails' do
|
35
35
|
JSON::JWT.stub(:decode, claims) do
|
36
36
|
prxauth.stub(:valid?, false) do
|
37
|
-
prxauth.call(env)
|
37
|
+
assert prxauth.call(env) == Rack::PrxAuth::INVALID_TOKEN
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -42,7 +42,7 @@ describe Rack::PrxAuth do
|
|
42
42
|
it 'returns 401 if access token has expired' do
|
43
43
|
JSON::JWT.stub(:decode, claims) do
|
44
44
|
prxauth.stub(:expired?, true) do
|
45
|
-
prxauth.call(env)
|
45
|
+
assert prxauth.call(env) == Rack::PrxAuth::INVALID_TOKEN
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -51,9 +51,8 @@ describe Rack::PrxAuth do
|
|
51
51
|
prxauth.stub(:decode_token, claims) do
|
52
52
|
prxauth.stub(:valid?, true) do
|
53
53
|
prxauth.call(env)['prx.auth'].tap do |token|
|
54
|
-
token.
|
55
|
-
token.
|
56
|
-
token.user_id.must_equal claims['sub']
|
54
|
+
assert token.instance_of? Rack::PrxAuth::TokenData
|
55
|
+
assert token.user_id == claims['sub']
|
57
56
|
end
|
58
57
|
end
|
59
58
|
end
|
@@ -64,11 +63,11 @@ describe Rack::PrxAuth do
|
|
64
63
|
it 'returns true if token is expired' do
|
65
64
|
claims['iat'] = Time.now.to_i - 4000
|
66
65
|
|
67
|
-
prxauth.send(:expired?, claims)
|
66
|
+
assert prxauth.send(:expired?, claims) == true
|
68
67
|
end
|
69
68
|
|
70
69
|
it 'returns false if it is valid' do
|
71
|
-
prxauth.send(:expired?, claims)
|
70
|
+
assert prxauth.send(:expired?, claims) == false
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
@@ -77,22 +76,22 @@ describe Rack::PrxAuth do
|
|
77
76
|
loc = nil
|
78
77
|
Rack::PrxAuth::Certificate.stub(:new, Proc.new{|l| loc = l}) do
|
79
78
|
Rack::PrxAuth.new(app, cert_location: :location)
|
80
|
-
loc
|
79
|
+
assert loc == :location
|
81
80
|
end
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
85
84
|
describe '#decode_token' do
|
86
85
|
it 'should return an empty result for a nil token' do
|
87
|
-
prxauth.send(:decode_token, nil)
|
86
|
+
assert prxauth.send(:decode_token, nil) == {}
|
88
87
|
end
|
89
88
|
|
90
89
|
it 'should return an empty result for an empty token' do
|
91
|
-
prxauth.send(:decode_token, {})
|
90
|
+
assert prxauth.send(:decode_token, {}) == {}
|
92
91
|
end
|
93
92
|
|
94
93
|
it 'should return an empty result for a malformed token' do
|
95
|
-
prxauth.send(:decode_token, 'asdfsadfsad')
|
94
|
+
assert prxauth.send(:decode_token, 'asdfsadfsad') == {}
|
96
95
|
end
|
97
96
|
end
|
98
97
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-prx_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eve Asher
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-04-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -139,11 +139,16 @@ files:
|
|
139
139
|
- LICENSE
|
140
140
|
- README.md
|
141
141
|
- Rakefile
|
142
|
+
- lib/prx_auth.rb
|
143
|
+
- lib/prx_auth/resource_map.rb
|
144
|
+
- lib/prx_auth/scope_list.rb
|
142
145
|
- lib/rack/prx_auth.rb
|
143
146
|
- lib/rack/prx_auth/certificate.rb
|
144
147
|
- lib/rack/prx_auth/token_data.rb
|
145
148
|
- lib/rack/prx_auth/version.rb
|
146
149
|
- rack-prx_auth.gemspec
|
150
|
+
- test/prx_auth/resource_map_test.rb
|
151
|
+
- test/prx_auth/scope_list_test.rb
|
147
152
|
- test/rack/prx_auth/certificate_test.rb
|
148
153
|
- test/rack/prx_auth/token_data_test.rb
|
149
154
|
- test/rack/prx_auth_test.rb
|
@@ -173,6 +178,8 @@ specification_version: 4
|
|
173
178
|
summary: Rack middleware that verifies and decodes a JWT token and attaches the token's
|
174
179
|
claims to env.
|
175
180
|
test_files:
|
181
|
+
- test/prx_auth/resource_map_test.rb
|
182
|
+
- test/prx_auth/scope_list_test.rb
|
176
183
|
- test/rack/prx_auth/certificate_test.rb
|
177
184
|
- test/rack/prx_auth/token_data_test.rb
|
178
185
|
- test/rack/prx_auth_test.rb
|