rack-prx_auth 0.3.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|