prx_auth 1.1.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -20
- data/lib/prx_auth/resource_map.rb +27 -19
- data/lib/prx_auth/scope_list.rb +67 -59
- data/lib/prx_auth/version.rb +1 -1
- data/lib/rack/prx_auth.rb +6 -1
- data/test/prx_auth/resource_map_test.rb +27 -0
- data/test/prx_auth/scope_list_test.rb +27 -0
- data/test/rack/prx_auth_test.rb +43 -7
- metadata +2 -3
- data/lib/rack/prx_auth/version.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 765ac2dcac47b990cfb7978891f92fe853d0e8001fc663a0099f90ef064f14a1
|
4
|
+
data.tar.gz: 8085236902300f65d458a6b66cd2904ff116c340b7c79a08fc17f274856693ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa5b7a5de59a4de7b0bc974b2ac8932acbf5117c070ea3d2ab602223696a5761eda9a46421d18dfb8c5612331456a42dfeaeae3c63480081c30c90d170de7d5c
|
7
|
+
data.tar.gz: 66759612cee8f4cf1788d9374934f2a79678e72923fec8a188399fd5f158616ca0a3bc371be66de12e8981cece7c958b0281aaf9a1753826ae816c3e090bd17a
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# PrxAuth
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/
|
4
|
-
[![Dependency Status](https://gemnasium.com/PRX/
|
5
|
-
[![Build Status](https://travis-ci.org/PRX/
|
6
|
-
[![Code Climate](https://codeclimate.com/github/PRX/
|
7
|
-
[![Coverage Status](https://coveralls.io/repos/PRX/
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/prx_auth.svg)](http://badge.fury.io/rb/prx_auth)
|
4
|
+
[![Dependency Status](https://gemnasium.com/PRX/prx_auth.svg)](https://gemnasium.com/PRX/prx_auth)
|
5
|
+
[![Build Status](https://travis-ci.org/PRX/prx_auth.svg?branch=master)](https://travis-ci.org/PRX/prx_auth)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/PRX/prx_auth/badges/gpa.svg)](https://codeclimate.com/github/PRX/prx_auth)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/PRX/prx_auth/badge.svg)](https://coveralls.io/r/PRX/prx_auth)
|
8
8
|
|
9
9
|
This gem adds middleware to a Rack application that decodes and verified a JSON Web Token (JWT) issued by PRX.org. If the JWT is invalid, the middleware will respond with a 401 Unauthorized. If the JWT was not issued by PRX (or the specified issuer), the request will continue through the middleware stack.
|
10
10
|
|
@@ -13,7 +13,7 @@ This gem adds middleware to a Rack application that decodes and verified a JSON
|
|
13
13
|
Add this line to your application's Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem '
|
16
|
+
gem 'prx_auth'
|
17
17
|
```
|
18
18
|
|
19
19
|
And then execute:
|
@@ -22,44 +22,51 @@ And then execute:
|
|
22
22
|
|
23
23
|
Or install it yourself as:
|
24
24
|
|
25
|
-
$ gem install
|
25
|
+
$ gem install prx_auth
|
26
26
|
|
27
27
|
In a non-Rails app, add the following to the application's config.ru file:
|
28
28
|
|
29
29
|
```ruby
|
30
|
+
require 'rack/prx_auth'
|
30
31
|
use Rack::PrxAuth, cert_location: [CERT LOCATION], issuer: [ISSUER]
|
31
32
|
```
|
32
33
|
The `cert_location` and `issuer` parameters are optional. See below.
|
33
34
|
|
34
35
|
## Usage
|
35
36
|
|
36
|
-
###
|
37
|
+
### Utility Classes
|
37
38
|
|
38
|
-
|
39
|
+
Right now, we just have ResourceMap and ScopeList which allow you to work with scopes the way they are handled in the id.prx.org tokens. Resource wildcards and namespaces are supported. By using ResourceMap and ScopeList, you can also perform set arithmetic while handling wildcard semantics.
|
40
|
+
|
41
|
+
### Rack::PrxAuth
|
42
|
+
|
43
|
+
#### The Request
|
44
|
+
|
45
|
+
Rack::PrxAuth looks for a token in the request's HTTP_AUTHORIZATION header. It expects that the header's content will take the form of 'Bearer <your token>'. If no HTTP_AUTHORIZATION header is present, the middlware passes the request to the next middleware.
|
39
46
|
|
40
47
|
We have another application that's in charge of making the token. It's called id.prx.org. Its job is to show a form for a user to enter credentials, validate those credentials, and then generate a JWT using PRX's private key. See http://openid.net/specs/openid-connect-implicit-1_0.html to find out what information is encoded in a JWT. Basically it's a hash containing, among other things, the user's ID, the issuer of the token, and when the token expires.
|
41
48
|
|
42
|
-
|
49
|
+
#### Configuration
|
43
50
|
|
44
|
-
Rack
|
51
|
+
Rack::PrxAuth takes two optional parameters, `issuer` and `cert_location`. See Installation for how to specify them.
|
45
52
|
|
46
|
-
By default,
|
53
|
+
By default, Rack::PrxAuth will assume that you want to make sure the JWT was issued by PRX. After decoding the JWT, Rack::PrxAuth checks the `issuer` field to make sure it's id.prx.org. If you want it to check for a different issuer, pass `issuer: <your issuer>` as a parameter.
|
47
54
|
|
48
|
-
Since the JWT was created using PRX's private key, rack-prx_auth needs to fetch PRX's public key to decode it. It does this by accessing the `cert_location` (default is https://id.prx.org/api/v1/certs), generating an OpenSSL::X509::Certificate based on its contents, and determining the public key from the certificate object. Should you wish to get your public key from a different certificate, you may specify a different endpoint by passing `cert_location: <your cert location>` as a parameter. Keep in mind that unless the certificate matches the private key used to make the JWT,
|
55
|
+
Since the JWT was created using PRX's private key, rack-prx_auth needs to fetch PRX's public key to decode it. It does this by accessing the `cert_location` (default is https://id.prx.org/api/v1/certs), generating an OpenSSL::X509::Certificate based on its contents, and determining the public key from the certificate object. Should you wish to get your public key from a different certificate, you may specify a different endpoint by passing `cert_location: <your cert location>` as a parameter. Keep in mind that unless the certificate matches the private key used to make the JWT, Rack::PrxAuth will return 401.
|
49
56
|
|
50
|
-
|
57
|
+
#### The Response
|
51
58
|
|
52
|
-
If the token isn't valid, meaning it's expired or it wasn't created using our private key,
|
59
|
+
If the token isn't valid, meaning it's expired or it wasn't created using our private key, Rack::PrxAuth will return 401 Unauthorized.
|
53
60
|
|
54
|
-
If there's nothing in the HTTP_AUTHORIZATION heading, there's something but JSON::JWT can't decode it, or the issuer field doesn't specify the correct issuer,
|
61
|
+
If there's nothing in the HTTP_AUTHORIZATION heading, there's something but JSON::JWT can't decode it, or the issuer field doesn't specify the correct issuer, Rack::PrxAuth just punts to the next piece of middleware.
|
55
62
|
|
56
|
-
If all goes well,
|
63
|
+
If all goes well, Rack::PrxAuth takes the decoded JWT and makes a TokenData object. Then it adds this object to the `env` with the key 'prx.auth'.
|
57
64
|
|
58
|
-
If you are using
|
65
|
+
If you are using Rack::PrxAuth in a Rails app, probably use [prx_auth-rails](https://github.com/PRX/prx_auth-rails) which will automatically install the middleware and add some helpful controller methods.
|
59
66
|
|
60
67
|
## Contributing
|
61
68
|
|
62
|
-
1. Fork it ( https://github.com/PRX/
|
69
|
+
1. Fork it ( https://github.com/PRX/prx_auth/fork )
|
63
70
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
64
71
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
65
72
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -1,13 +1,20 @@
|
|
1
1
|
module PrxAuth
|
2
|
-
class ResourceMap
|
2
|
+
class ResourceMap < Hash
|
3
3
|
WILDCARD_KEY = '*'
|
4
4
|
|
5
5
|
def initialize(mapped_values)
|
6
|
+
super() do |hash, key|
|
7
|
+
if key == WILDCARD_KEY
|
8
|
+
@wildcard
|
9
|
+
else
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
6
13
|
input = mapped_values.clone
|
7
14
|
@wildcard = ScopeList.new(input.delete(WILDCARD_KEY)||'')
|
8
|
-
|
9
|
-
[key
|
10
|
-
end
|
15
|
+
input.each do |(key, values)|
|
16
|
+
self[key.to_s] = ScopeList.new(values)
|
17
|
+
end
|
11
18
|
end
|
12
19
|
|
13
20
|
def contains?(resource, namespace=nil, scope=nil)
|
@@ -18,7 +25,7 @@ module PrxAuth
|
|
18
25
|
|
19
26
|
@wildcard.contains?(namespace, scope)
|
20
27
|
else
|
21
|
-
mapped_resource =
|
28
|
+
mapped_resource = self[resource]
|
22
29
|
|
23
30
|
if mapped_resource && !namespace.nil?
|
24
31
|
mapped_resource.contains?(namespace, scope) || @wildcard.contains?(namespace, scope)
|
@@ -30,9 +37,17 @@ module PrxAuth
|
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
40
|
+
def [](key)
|
41
|
+
super(key.to_s)
|
42
|
+
end
|
43
|
+
|
44
|
+
def []=(key, value)
|
45
|
+
super(key.to_s, value)
|
46
|
+
end
|
47
|
+
|
33
48
|
def condense
|
34
49
|
condensed_wildcard = @wildcard.condense
|
35
|
-
condensed_map = Hash[
|
50
|
+
condensed_map = Hash[map do |resource, list|
|
36
51
|
[resource, (list - condensed_wildcard).condense]
|
37
52
|
end]
|
38
53
|
ResourceMap.new(condensed_map.merge(WILDCARD_KEY => condensed_wildcard))
|
@@ -63,7 +78,7 @@ module PrxAuth
|
|
63
78
|
result[resource] = list_for_resource(resource) - (other_wildcard + other_map.list_for_resource(resource))
|
64
79
|
end
|
65
80
|
|
66
|
-
if @wildcard
|
81
|
+
if @wildcard.length
|
67
82
|
result[WILDCARD_KEY] = @wildcard - other_wildcard
|
68
83
|
end
|
69
84
|
|
@@ -87,7 +102,7 @@ module PrxAuth
|
|
87
102
|
end
|
88
103
|
end
|
89
104
|
|
90
|
-
if @wildcard
|
105
|
+
if @wildcard.length > 0
|
91
106
|
result[WILDCARD_KEY] = @wildcard - (@wildcard - other_wildcard)
|
92
107
|
end
|
93
108
|
|
@@ -95,20 +110,14 @@ module PrxAuth
|
|
95
110
|
end
|
96
111
|
|
97
112
|
def as_json(opts={})
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
def freeze
|
102
|
-
@map.freeze
|
103
|
-
@wildcard.freeze
|
104
|
-
self
|
113
|
+
super(opts).merge(@wildcard.length > 0 ? {WILDCARD_KEY => @wildcard}.as_json(opts) : {})
|
105
114
|
end
|
106
115
|
|
107
116
|
def resources(namespace=nil, scope=nil)
|
108
117
|
if namespace.nil?
|
109
|
-
|
118
|
+
keys
|
110
119
|
else
|
111
|
-
|
120
|
+
select do |name, list|
|
112
121
|
list.contains?(namespace, scope) || @wildcard.contains?(namespace, scope)
|
113
122
|
end.map(&:first)
|
114
123
|
end
|
@@ -117,8 +126,7 @@ module PrxAuth
|
|
117
126
|
protected
|
118
127
|
|
119
128
|
def list_for_resource(resource)
|
120
|
-
|
121
|
-
@map[resource.to_s]
|
129
|
+
self[resource.to_s]
|
122
130
|
end
|
123
131
|
end
|
124
132
|
end
|
data/lib/prx_auth/scope_list.rb
CHANGED
@@ -1,52 +1,87 @@
|
|
1
1
|
module PrxAuth
|
2
|
-
class ScopeList
|
2
|
+
class ScopeList < Array
|
3
3
|
SCOPE_SEPARATOR = ' '
|
4
4
|
NAMESPACE_SEPARATOR = ':'
|
5
5
|
NO_NAMESPACE = :_
|
6
6
|
|
7
|
+
Entry = Struct.new(:namespace, :scope, :string)
|
8
|
+
|
9
|
+
class Entry
|
10
|
+
def ==(other_entry)
|
11
|
+
namespace == other_entry.namespace && scope == other_entry.scope
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
string
|
16
|
+
end
|
17
|
+
|
18
|
+
def namespaced?
|
19
|
+
!(namespace.nil? || namespace == NO_NAMESPACE)
|
20
|
+
end
|
21
|
+
|
22
|
+
def unnamespaced
|
23
|
+
if namespaced?
|
24
|
+
Entry.new(NO_NAMESPACE, scope, string.split(':').last)
|
25
|
+
else
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
"#<ScopeList::Entry \"#{to_s}\">"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
7
35
|
def self.new(list)
|
8
36
|
case list
|
9
37
|
when PrxAuth::ScopeList then list
|
38
|
+
when Array then super(list.join(' '))
|
10
39
|
else super(list)
|
11
40
|
end
|
12
41
|
end
|
13
42
|
|
14
43
|
def initialize(list)
|
15
44
|
@string = list
|
45
|
+
@string.split(SCOPE_SEPARATOR).each do |value|
|
46
|
+
next if value.length < 1
|
47
|
+
|
48
|
+
parts = value.split(NAMESPACE_SEPARATOR, 2)
|
49
|
+
if parts.length == 2
|
50
|
+
push Entry.new(symbolize(parts[0]), symbolize(parts[1]), value)
|
51
|
+
else
|
52
|
+
push Entry.new(NO_NAMESPACE, symbolize(parts[0]), value)
|
53
|
+
end
|
54
|
+
end
|
16
55
|
end
|
17
56
|
|
18
57
|
def contains?(namespace, scope=nil)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
58
|
+
entries = if scope.nil?
|
59
|
+
scope, namespace = namespace, NO_NAMESPACE
|
60
|
+
[Entry.new(namespace, symbolize(scope), nil)]
|
61
|
+
else
|
62
|
+
scope = symbolize(scope)
|
63
|
+
namespace = symbolize(namespace)
|
64
|
+
[Entry.new(namespace, scope, nil), Entry.new(NO_NAMESPACE, scope, nil)]
|
65
|
+
end
|
66
|
+
|
67
|
+
entries.any? do |possible_match|
|
68
|
+
include?(possible_match)
|
26
69
|
end
|
27
70
|
end
|
28
71
|
|
29
|
-
def freeze
|
30
|
-
@string.freeze
|
31
|
-
self
|
32
|
-
end
|
33
|
-
|
34
72
|
def to_s
|
35
73
|
@string
|
36
74
|
end
|
37
75
|
|
38
76
|
def condense
|
39
77
|
tripped = false
|
40
|
-
result =
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
tripped = true
|
49
|
-
end
|
78
|
+
result = []
|
79
|
+
|
80
|
+
each do |entry|
|
81
|
+
if entry.namespaced? && include?(entry.unnamespaced)
|
82
|
+
tripped = true
|
83
|
+
else
|
84
|
+
result << entry
|
50
85
|
end
|
51
86
|
end
|
52
87
|
|
@@ -67,13 +102,11 @@ module PrxAuth
|
|
67
102
|
tripped = false
|
68
103
|
result = []
|
69
104
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
result << scope_string(namespace, scope)
|
76
|
-
end
|
105
|
+
each do |entry|
|
106
|
+
if other_scope_list.include?(entry) || other_scope_list.include?(entry.unnamespaced)
|
107
|
+
tripped = true
|
108
|
+
else
|
109
|
+
result << entry
|
77
110
|
end
|
78
111
|
end
|
79
112
|
|
@@ -93,39 +126,14 @@ module PrxAuth
|
|
93
126
|
def &(other_list)
|
94
127
|
return ScopeList.new('') if other_list.nil?
|
95
128
|
|
96
|
-
self - (self - other_list)
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
|
101
|
-
def map
|
102
|
-
@parsed_map ||= empty_map.tap do |map|
|
103
|
-
@string.split(SCOPE_SEPARATOR).each do |value|
|
104
|
-
next if value.length < 1
|
105
|
-
|
106
|
-
parts = value.split(NAMESPACE_SEPARATOR, 2)
|
107
|
-
if parts.length == 2
|
108
|
-
map[symbolize(parts[0])] << symbolize(parts[1])
|
109
|
-
else
|
110
|
-
map[NO_NAMESPACE] << symbolize(parts[0])
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
129
|
+
self - (self - other_list) + (other_list - (other_list - self))
|
114
130
|
end
|
115
131
|
|
116
|
-
def
|
117
|
-
|
118
|
-
scope.to_s
|
119
|
-
else
|
120
|
-
[ns, scope].join(NAMESPACE_SEPARATOR)
|
121
|
-
end
|
132
|
+
def ==(other)
|
133
|
+
condense.sort_by(&:to_s) == other.condense.sort_by(&:to_s)
|
122
134
|
end
|
123
135
|
|
124
|
-
|
125
|
-
@empty_map ||= Hash.new do |hash, key|
|
126
|
-
hash[key] = []
|
127
|
-
end
|
128
|
-
end
|
136
|
+
private
|
129
137
|
|
130
138
|
def symbolize(value)
|
131
139
|
case value
|
data/lib/prx_auth/version.rb
CHANGED
data/lib/rack/prx_auth.rb
CHANGED
@@ -53,7 +53,12 @@ module Rack
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def expired?(claims)
|
56
|
-
Time.now.to_i
|
56
|
+
now = Time.now.to_i - 30 # 30 second clock jitter allowance
|
57
|
+
if claims['iat'] <= claims['exp']
|
58
|
+
now > claims['exp']
|
59
|
+
else
|
60
|
+
now > (claims['iat'] + claims['exp'])
|
61
|
+
end
|
57
62
|
end
|
58
63
|
|
59
64
|
def should_validate_token?(claims)
|
@@ -155,4 +155,31 @@ describe PrxAuth::ResourceMap do
|
|
155
155
|
assert map.contains?("*", :wild)
|
156
156
|
end
|
157
157
|
end
|
158
|
+
|
159
|
+
describe '#as_json' do
|
160
|
+
it 'does not include wildcard key if list is empty' do
|
161
|
+
map = new_map("foo" => "asdf")
|
162
|
+
refute map.as_json.has_key?('*')
|
163
|
+
map2 = new_map("foo" => "asdf", "*" => "")
|
164
|
+
refute map2.as_json.has_key?('*')
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'includes the wildcard key if the list is not empty' do
|
168
|
+
map = new_map("*" => "asdf")
|
169
|
+
assert map.as_json.has_key?('*')
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#[]' do
|
174
|
+
it 'automatically stringifies' do
|
175
|
+
refute_nil map[123]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '#[]=' do
|
180
|
+
it 'automatically stringifies' do
|
181
|
+
map[789] = PrxAuth::ScopeList.new("")
|
182
|
+
refute_nil map["789"]
|
183
|
+
end
|
184
|
+
end
|
158
185
|
end
|
@@ -70,6 +70,12 @@ describe PrxAuth::ScopeList do
|
|
70
70
|
sl = new_list('one two') - nil
|
71
71
|
assert sl.contains?(:one) && sl.contains?(:two)
|
72
72
|
end
|
73
|
+
|
74
|
+
it 'maintains dashes and capitalization in the result' do
|
75
|
+
sl = new_list('The-Beginning the-middle the-end') - new_list('the-Middle')
|
76
|
+
assert sl.to_s == 'The-Beginning the-end'
|
77
|
+
end
|
78
|
+
|
73
79
|
end
|
74
80
|
|
75
81
|
describe '#+' do
|
@@ -98,5 +104,26 @@ describe PrxAuth::ScopeList do
|
|
98
104
|
sl = new_list('one') & nil
|
99
105
|
assert !sl.contains?(:one)
|
100
106
|
end
|
107
|
+
|
108
|
+
it 'works when either side has non-namespaced values correctly' do
|
109
|
+
sl = PrxAuth::ScopeList.new('foo:bar') & PrxAuth::ScopeList.new('bar')
|
110
|
+
assert sl.contains?(:foo, :bar)
|
111
|
+
refute sl.contains?(:bar)
|
112
|
+
|
113
|
+
sl = PrxAuth::ScopeList.new('bar') & PrxAuth::ScopeList.new('foo:bar')
|
114
|
+
assert sl.contains?(:foo, :bar)
|
115
|
+
refute sl.contains?(:bar)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '==' do
|
120
|
+
|
121
|
+
it 'is equal when they are functionally equal' do
|
122
|
+
assert_equal PrxAuth::ScopeList.new("foo ns:foo bar ns2:baz"), PrxAuth::ScopeList.new("ns2:baz bar foo")
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'is not equal when they are not functionally equal' do
|
126
|
+
refute_equal PrxAuth::ScopeList.new("foo bar"), PrxAuth::ScopeList.new("foo:bar bar:foo")
|
127
|
+
end
|
101
128
|
end
|
102
129
|
end
|
data/test/rack/prx_auth_test.rb
CHANGED
@@ -5,7 +5,9 @@ describe Rack::PrxAuth do
|
|
5
5
|
let(:prxauth) { Rack::PrxAuth.new(app) }
|
6
6
|
let(:fake_token) { 'afawefawefawefawegstgnsrtiohnlijblublwjnvrtoign'}
|
7
7
|
let(:env) { {'HTTP_AUTHORIZATION' => 'Bearer ' + fake_token } }
|
8
|
-
let(:
|
8
|
+
let(:iat) { Time.now.to_i }
|
9
|
+
let(:exp) { 3600 }
|
10
|
+
let(:claims) { {'sub'=>3, 'exp'=>exp, 'iat'=>iat, 'token_type'=>'bearer', 'scope'=>nil, 'iss'=>'id.prx.org'} }
|
9
11
|
|
10
12
|
describe '#call' do
|
11
13
|
it 'does nothing if there is no authorization header' do
|
@@ -59,15 +61,49 @@ describe Rack::PrxAuth do
|
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
|
-
describe '#
|
63
|
-
it 'returns true if token is expired' do
|
64
|
-
claims['iat'] = Time.now.to_i - 4000
|
64
|
+
describe '#expired?' do
|
65
65
|
|
66
|
-
|
66
|
+
def expired?(claims)
|
67
|
+
prxauth.send(:expired?, claims)
|
67
68
|
end
|
68
69
|
|
69
|
-
|
70
|
-
|
70
|
+
describe 'with a malformed exp' do
|
71
|
+
let(:iat) { Time.now.to_i }
|
72
|
+
let(:exp) { 3600 }
|
73
|
+
|
74
|
+
it 'is expired if iat + exp are in the past' do
|
75
|
+
claims['iat'] -= 3631
|
76
|
+
|
77
|
+
assert expired?(claims)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'is not expired if iat + exp are in the future' do
|
81
|
+
claims['iat'] = Time.now.to_i - 3599
|
82
|
+
|
83
|
+
refute expired?(claims)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'allows a 30s clock jitter' do
|
87
|
+
claims['iat'] = Time.now.to_i - 3629
|
88
|
+
|
89
|
+
refute expired?(claims)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'with a corrected exp' do
|
94
|
+
let(:iat) { Time.now.to_i - 3600 }
|
95
|
+
let(:exp) { Time.now.to_i + 1 }
|
96
|
+
|
97
|
+
it 'is not expired if exp is in the future' do
|
98
|
+
refute expired?(claims)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'is expired if exp is in the past (with 30s jitter grace)' do
|
102
|
+
claims['exp'] = Time.now.to_i - 31
|
103
|
+
assert expired?(claims)
|
104
|
+
claims['exp'] = Time.now.to_i - 29
|
105
|
+
refute expired?(claims)
|
106
|
+
end
|
71
107
|
end
|
72
108
|
end
|
73
109
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prx_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.4.1
|
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-09-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -146,7 +146,6 @@ files:
|
|
146
146
|
- lib/rack/prx_auth.rb
|
147
147
|
- lib/rack/prx_auth/certificate.rb
|
148
148
|
- lib/rack/prx_auth/token_data.rb
|
149
|
-
- lib/rack/prx_auth/version.rb
|
150
149
|
- prx_auth.gemspec
|
151
150
|
- test/prx_auth/resource_map_test.rb
|
152
151
|
- test/prx_auth/scope_list_test.rb
|