fridge 0.3.0 → 0.4.3
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 +5 -5
- data/.github/CODEOWNERS +1 -0
- data/.travis.yml +4 -2
- data/Gemfile +3 -0
- data/README.md +1 -3
- data/fridge.gemspec +7 -6
- data/lib/fridge.rb +4 -1
- data/lib/fridge/access_token.rb +78 -32
- data/lib/fridge/expired_token.rb +4 -0
- data/lib/fridge/rails_helpers.rb +25 -8
- data/lib/fridge/version.rb +1 -1
- data/spec/fixtures/app.rb +2 -5
- data/spec/fridge/access_token_spec.rb +56 -4
- data/spec/fridge/rails_helpers_spec.rb +162 -161
- data/spec/spec_helper.rb +11 -3
- metadata +29 -30
- data/spec/fixtures/controller.rb +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c01604ddabbbd9a954e9fe73e1567aa0232509c30ed09e7694315131e0402abf
|
|
4
|
+
data.tar.gz: fd4199b0194b7a63e7062c630dc9bb58c75eab607e27ebf13d24fe001a654c40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2df7422238fac73bb4263af3af697d049b8ae870ed4c1610c40fdde3bcfd422b0cf8ac5f92a3889201b2aec5d222cda04fc49f5ee1797f6a0a2e3ea615094cb7
|
|
7
|
+
data.tar.gz: e11293fdad80f5a7dfa6f6538b244f67ed59fc8e9867dde34c49c1067555936881b4d7b0de9f0ab5910a2a57b6d68dec0bd76462c888f7531c12ccdd6beb5d47
|
data/.github/CODEOWNERS
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @dawenster
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -80,6 +80,4 @@ store_session_cookie(access_token)
|
|
|
80
80
|
|
|
81
81
|
MIT License, see [LICENSE](LICENSE.md) for details.
|
|
82
82
|
|
|
83
|
-
Copyright (c)
|
|
84
|
-
|
|
85
|
-
[<img src="https://s.gravatar.com/avatar/f7790b867ae619ae0496460aa28c5861?s=60" style="border-radius: 50%;" alt="@fancyremarker" />](https://github.com/fancyremarker)
|
|
83
|
+
Copyright (c) 2019 [Aptible](https://www.aptible.com) and contributors.
|
data/fridge.gemspec
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
|
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
5
|
|
|
@@ -16,17 +17,17 @@ Gem::Specification.new do |spec|
|
|
|
16
17
|
spec.license = 'MIT'
|
|
17
18
|
|
|
18
19
|
spec.files = `git ls-files`.split($RS)
|
|
19
|
-
spec.test_files = spec.files.grep(
|
|
20
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
|
20
21
|
spec.require_paths = ['lib']
|
|
21
22
|
|
|
22
23
|
spec.add_dependency 'gem_config'
|
|
23
|
-
spec.add_dependency 'jwt', '~>
|
|
24
|
+
spec.add_dependency 'jwt', '~> 1.5.6'
|
|
24
25
|
|
|
25
|
-
spec.add_development_dependency 'bundler', '~> 1.5'
|
|
26
26
|
spec.add_development_dependency 'aptible-tasks'
|
|
27
|
-
spec.add_development_dependency '
|
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
|
28
|
+
spec.add_development_dependency 'pry'
|
|
28
29
|
spec.add_development_dependency 'rails'
|
|
29
|
-
spec.add_development_dependency '
|
|
30
|
+
spec.add_development_dependency 'rake'
|
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
30
32
|
spec.add_development_dependency 'rspec-rails'
|
|
31
|
-
spec.add_development_dependency 'pry'
|
|
32
33
|
end
|
data/lib/fridge.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'fridge/version'
|
|
|
4
4
|
require 'fridge/access_token'
|
|
5
5
|
require 'fridge/serialization_error'
|
|
6
6
|
require 'fridge/invalid_token'
|
|
7
|
+
require 'fridge/expired_token'
|
|
7
8
|
|
|
8
9
|
require 'fridge/railtie' if defined?(Rails)
|
|
9
10
|
|
|
@@ -14,7 +15,9 @@ module Fridge
|
|
|
14
15
|
has :private_key, classes: [String]
|
|
15
16
|
has :public_key, classes: [String]
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
# rubocop:disable Style/PercentLiteralDelimiters
|
|
19
|
+
has :signing_algorithm, values: %w[RS512 RS256], default: 'RS512'
|
|
20
|
+
# rubocop:enable Style/PercentLiteralDelimiters
|
|
18
21
|
|
|
19
22
|
# A validator must raise an exception or return a false value for an
|
|
20
23
|
# invalid token
|
data/lib/fridge/access_token.rb
CHANGED
|
@@ -2,10 +2,9 @@ require 'jwt'
|
|
|
2
2
|
|
|
3
3
|
module Fridge
|
|
4
4
|
class AccessToken
|
|
5
|
-
attr_accessor :id, :issuer, :subject, :scope, :expires_at,
|
|
5
|
+
attr_accessor :id, :issuer, :subject, :scope, :expires_at, :actor,
|
|
6
6
|
:jwt, :attributes
|
|
7
7
|
|
|
8
|
-
# rubocop:disable MethodLength
|
|
9
8
|
def initialize(jwt_or_options = nil)
|
|
10
9
|
options = case jwt_or_options
|
|
11
10
|
when String
|
|
@@ -15,13 +14,12 @@ module Fridge
|
|
|
15
14
|
when Hash then jwt_or_options
|
|
16
15
|
else {}
|
|
17
16
|
end
|
|
18
|
-
|
|
17
|
+
|
|
18
|
+
[:id, :issuer, :subject, :scope, :expires_at, :actor].each do |key|
|
|
19
19
|
send "#{key}=", options.delete(key)
|
|
20
20
|
end
|
|
21
|
-
self.attributes = options
|
|
22
|
-
self.attributes = Hash[attributes.map { |k, v| [k.to_sym, v] }]
|
|
21
|
+
self.attributes = options
|
|
23
22
|
end
|
|
24
|
-
# rubocop:enable MethodLength
|
|
25
23
|
|
|
26
24
|
def to_s
|
|
27
25
|
serialize
|
|
@@ -29,38 +27,32 @@ module Fridge
|
|
|
29
27
|
|
|
30
28
|
def serialize
|
|
31
29
|
return jwt if jwt
|
|
30
|
+
|
|
32
31
|
validate_parameters!
|
|
33
32
|
validate_private_key!
|
|
34
33
|
encode_and_sign
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def encode_and_sign
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
rescue
|
|
37
|
+
h = {}
|
|
38
|
+
[:id, :issuer, :subject, :scope, :expires_at, :actor].each do |key|
|
|
39
|
+
h[key] = send(key)
|
|
40
|
+
end
|
|
41
|
+
h.merge!(attributes)
|
|
42
|
+
h = encode_for_jwt(h)
|
|
43
|
+
JWT.encode(h, private_key, algorithm)
|
|
44
|
+
rescue StandardError
|
|
46
45
|
raise SerializationError, 'Invalid private key or signing algorithm'
|
|
47
46
|
end
|
|
48
47
|
|
|
49
|
-
# rubocop:disable MethodLength
|
|
50
48
|
def decode_and_verify(jwt)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
expires_at: Time.at(hash.delete('exp'))
|
|
58
|
-
}
|
|
59
|
-
base.merge(hash)
|
|
60
|
-
rescue JWT::DecodeError
|
|
61
|
-
raise InvalidToken, 'Invalid access token'
|
|
49
|
+
payload, _header = JWT.decode(jwt, public_key, true, algorithm: algorithm)
|
|
50
|
+
decode_from_jwt(payload)
|
|
51
|
+
rescue JWT::ExpiredSignature => e
|
|
52
|
+
raise ExpiredToken, e.message
|
|
53
|
+
rescue JWT::DecodeError => e
|
|
54
|
+
raise InvalidToken, e.message
|
|
62
55
|
end
|
|
63
|
-
# rubocop:enable MethodLength
|
|
64
56
|
|
|
65
57
|
def downgrade
|
|
66
58
|
self.scope = 'read'
|
|
@@ -76,8 +68,9 @@ module Fridge
|
|
|
76
68
|
|
|
77
69
|
def private_key
|
|
78
70
|
return unless config.private_key
|
|
71
|
+
|
|
79
72
|
@private_key ||= OpenSSL::PKey::RSA.new(config.private_key)
|
|
80
|
-
rescue
|
|
73
|
+
rescue StandardError
|
|
81
74
|
nil
|
|
82
75
|
end
|
|
83
76
|
|
|
@@ -87,7 +80,7 @@ module Fridge
|
|
|
87
80
|
elsif config.public_key
|
|
88
81
|
@public_key ||= OpenSSL::PKey::RSA.new(config.public_key)
|
|
89
82
|
end
|
|
90
|
-
rescue
|
|
83
|
+
rescue StandardError
|
|
91
84
|
nil
|
|
92
85
|
end
|
|
93
86
|
|
|
@@ -109,19 +102,72 @@ module Fridge
|
|
|
109
102
|
end
|
|
110
103
|
end
|
|
111
104
|
|
|
105
|
+
def respond_to_missing?(method, include_private = false)
|
|
106
|
+
attributes.key?(method) || super
|
|
107
|
+
end
|
|
108
|
+
|
|
112
109
|
def validate_parameters!
|
|
113
110
|
[:subject, :expires_at].each do |attribute|
|
|
114
111
|
next if send(attribute)
|
|
115
|
-
|
|
112
|
+
|
|
113
|
+
raise SerializationError, "Missing attribute: #{attribute}"
|
|
116
114
|
end
|
|
117
115
|
end
|
|
118
116
|
|
|
119
117
|
def validate_private_key!
|
|
120
|
-
|
|
118
|
+
raise SerializationError, 'No private key configured' unless private_key
|
|
121
119
|
end
|
|
122
120
|
|
|
123
121
|
def validate_public_key!
|
|
124
|
-
|
|
122
|
+
raise SerializationError, 'No public key configured' unless public_key
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Internally, we use "subject" to refer to "sub", and so on. We also
|
|
126
|
+
# represent some objects (expiry) differently. These functions do the
|
|
127
|
+
# mapping from Fridge to JWT and vice-versa.
|
|
128
|
+
|
|
129
|
+
def encode_for_jwt(hash)
|
|
130
|
+
hash = hash.dup
|
|
131
|
+
|
|
132
|
+
out = {
|
|
133
|
+
id: hash.delete(:id),
|
|
134
|
+
iss: hash.delete(:issuer),
|
|
135
|
+
sub: hash.delete(:subject),
|
|
136
|
+
scope: hash.delete(:scope)
|
|
137
|
+
}.delete_if { |_, v| v.nil? }
|
|
138
|
+
|
|
139
|
+
# Unfortunately, nil.to_i returns 0, which means we can't
|
|
140
|
+
# easily clean out exp if we include it although it wasn't passed
|
|
141
|
+
# in like we do for other keys. So, we only include it if it's
|
|
142
|
+
# actually passed in and non-nil. Either way, we delete the keys.
|
|
143
|
+
hash.delete(:expires_at).tap { |e| out[:exp] = e.to_i if e }
|
|
144
|
+
hash.delete(:actor).tap { |a| out[:act] = encode_for_jwt(a) if a }
|
|
145
|
+
|
|
146
|
+
# Extra attributes passed through as-is
|
|
147
|
+
out.merge!(hash)
|
|
148
|
+
|
|
149
|
+
out
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def decode_from_jwt(hash)
|
|
153
|
+
hash = hash.dup
|
|
154
|
+
|
|
155
|
+
out = {
|
|
156
|
+
id: hash.delete('id'),
|
|
157
|
+
issuer: hash.delete('iss'),
|
|
158
|
+
subject: hash.delete('sub'),
|
|
159
|
+
scope: hash.delete('scope')
|
|
160
|
+
}.delete_if { |_, v| v.nil? }
|
|
161
|
+
|
|
162
|
+
hash.delete('exp').tap { |e| out[:expires_at] = Time.at(e) if e }
|
|
163
|
+
hash.delete('act').tap { |a| out[:actor] = decode_from_jwt(a) if a }
|
|
164
|
+
|
|
165
|
+
# Extra attributes
|
|
166
|
+
hash.delete_if { |_, v| v.nil? }
|
|
167
|
+
hash = Hash[hash.map { |k, v| [k.to_sym, v] }]
|
|
168
|
+
out.merge!(hash)
|
|
169
|
+
|
|
170
|
+
out
|
|
125
171
|
end
|
|
126
172
|
end
|
|
127
173
|
end
|
data/lib/fridge/rails_helpers.rb
CHANGED
|
@@ -15,8 +15,13 @@ module Fridge
|
|
|
15
15
|
current_token.subject if current_token
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def token_actor
|
|
19
|
+
current_token.actor if current_token
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
def current_token
|
|
19
23
|
return unless bearer_token
|
|
24
|
+
|
|
20
25
|
@current_token ||= AccessToken.new(bearer_token).tap do |token|
|
|
21
26
|
validate_token!(token)
|
|
22
27
|
end
|
|
@@ -31,12 +36,17 @@ module Fridge
|
|
|
31
36
|
session_token.subject if session_token
|
|
32
37
|
end
|
|
33
38
|
|
|
39
|
+
def session_actor
|
|
40
|
+
session_token.actor if session_token
|
|
41
|
+
end
|
|
42
|
+
|
|
34
43
|
def session_token
|
|
35
44
|
return unless session_cookie
|
|
45
|
+
|
|
36
46
|
@session_token ||= AccessToken.new(session_cookie).tap do |token|
|
|
37
47
|
validate_token!(token).downgrade
|
|
38
48
|
end
|
|
39
|
-
rescue
|
|
49
|
+
rescue StandardError
|
|
40
50
|
clear_session_cookie
|
|
41
51
|
end
|
|
42
52
|
|
|
@@ -44,7 +54,7 @@ module Fridge
|
|
|
44
54
|
def validate_token(access_token)
|
|
45
55
|
validator = Fridge.configuration.validator
|
|
46
56
|
validator.call(access_token) && access_token
|
|
47
|
-
rescue
|
|
57
|
+
rescue StandardError
|
|
48
58
|
false
|
|
49
59
|
end
|
|
50
60
|
|
|
@@ -54,7 +64,7 @@ module Fridge
|
|
|
54
64
|
if validator.call(access_token)
|
|
55
65
|
access_token
|
|
56
66
|
else
|
|
57
|
-
|
|
67
|
+
raise InvalidToken, 'Rejected by validator'
|
|
58
68
|
end
|
|
59
69
|
end
|
|
60
70
|
|
|
@@ -78,12 +88,12 @@ module Fridge
|
|
|
78
88
|
end
|
|
79
89
|
|
|
80
90
|
def clear_session_cookie
|
|
81
|
-
cookies.delete fridge_cookie_name, domain:
|
|
91
|
+
cookies.delete fridge_cookie_name, domain: auth_domain
|
|
82
92
|
nil
|
|
83
93
|
end
|
|
84
94
|
|
|
85
95
|
def write_shared_cookie(name, value, options = {})
|
|
86
|
-
|
|
96
|
+
raise 'Can only write string cookie values' unless value.is_a?(String)
|
|
87
97
|
|
|
88
98
|
cookies[name] = {
|
|
89
99
|
value: value,
|
|
@@ -95,9 +105,10 @@ module Fridge
|
|
|
95
105
|
cookies[name]
|
|
96
106
|
end
|
|
97
107
|
|
|
98
|
-
def fetch_shared_cookie(name
|
|
108
|
+
def fetch_shared_cookie(name)
|
|
99
109
|
return read_shared_cookie(name) if read_shared_cookie(name)
|
|
100
|
-
|
|
110
|
+
|
|
111
|
+
write_shared_cookie(yield)
|
|
101
112
|
end
|
|
102
113
|
|
|
103
114
|
def delete_shared_cookie(name)
|
|
@@ -110,8 +121,14 @@ module Fridge
|
|
|
110
121
|
|
|
111
122
|
def fridge_cookie_options
|
|
112
123
|
secure = !Rails.env.development?
|
|
113
|
-
options = { domain:
|
|
124
|
+
options = { domain: auth_domain, secure: secure, httponly: true }
|
|
114
125
|
options.merge(Fridge.configuration.cookie_options)
|
|
115
126
|
end
|
|
127
|
+
|
|
128
|
+
def auth_domain
|
|
129
|
+
Aptible::Auth.configuration.root_url.sub(%r{^https?://}, '')
|
|
130
|
+
rescue StandardError
|
|
131
|
+
'auth.aptible.com'
|
|
132
|
+
end
|
|
116
133
|
end
|
|
117
134
|
end
|
data/lib/fridge/version.rb
CHANGED
data/spec/fixtures/app.rb
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
require 'active_support/all'
|
|
2
|
-
require 'action_controller'
|
|
3
|
-
require 'action_dispatch'
|
|
4
|
-
|
|
5
1
|
module Rails
|
|
6
2
|
class App
|
|
7
3
|
def env_config
|
|
@@ -10,6 +6,7 @@ module Rails
|
|
|
10
6
|
|
|
11
7
|
def routes
|
|
12
8
|
return @routes if defined?(@routes)
|
|
9
|
+
|
|
13
10
|
@routes = ActionDispatch::Routing::RouteSet.new
|
|
14
11
|
@routes.draw do
|
|
15
12
|
resources :posts
|
|
@@ -19,6 +16,6 @@ module Rails
|
|
|
19
16
|
end
|
|
20
17
|
|
|
21
18
|
def self.application
|
|
22
|
-
@
|
|
19
|
+
@application ||= App.new
|
|
23
20
|
end
|
|
24
21
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
+
require 'json'
|
|
2
3
|
|
|
3
4
|
describe Fridge::AccessToken do
|
|
4
5
|
describe '#initialize' do
|
|
@@ -13,19 +14,39 @@ describe Fridge::AccessToken do
|
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
it 'should accept a JWT' do
|
|
16
|
-
jwt = JWT.encode(
|
|
17
|
+
jwt = JWT.encode(
|
|
18
|
+
{ id: 'foobar', exp: Time.now.to_i + 10 },
|
|
19
|
+
private_key, 'RS512'
|
|
20
|
+
)
|
|
17
21
|
access_token = described_class.new(jwt)
|
|
18
22
|
expect(access_token.id).to eq 'foobar'
|
|
19
23
|
end
|
|
20
24
|
|
|
21
25
|
it 'should raise an error on an invalid JWT' do
|
|
22
|
-
expect { described_class.new('foobar') }
|
|
26
|
+
expect { described_class.new('foobar') }
|
|
27
|
+
.to raise_error Fridge::InvalidToken
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
it 'should raise an error on an incorrectly signed JWT' do
|
|
26
31
|
jwt = JWT.encode({ id: 'foobar' }, OpenSSL::PKey::RSA.new(1024), 'RS512')
|
|
27
32
|
expect { described_class.new(jwt) }.to raise_error Fridge::InvalidToken
|
|
28
33
|
end
|
|
34
|
+
|
|
35
|
+
it 'should raise an error on an expired JWT' do
|
|
36
|
+
jwt = JWT.encode(
|
|
37
|
+
{ id: 'foobar', exp: Time.now.to_i - 10 },
|
|
38
|
+
private_key, 'RS512'
|
|
39
|
+
)
|
|
40
|
+
expect { described_class.new(jwt) }.to raise_error(Fridge::ExpiredToken)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# http://bit.ly/jwt-none-vulnerability
|
|
44
|
+
it 'should raise an error with { "alg": "none" }' do
|
|
45
|
+
jwt = "#{Base64.encode64({ typ: 'JWT', alg: 'none' }.to_json).chomp}." \
|
|
46
|
+
"#{Base64.encode64({ id: 'foobar' }.to_json).chomp}"
|
|
47
|
+
expect(JWT.decode(jwt, nil, false)[0]).to eq('id' => 'foobar')
|
|
48
|
+
expect { described_class.new(jwt) }.to raise_error Fridge::InvalidToken
|
|
49
|
+
end
|
|
29
50
|
end
|
|
30
51
|
|
|
31
52
|
describe '#serialize' do
|
|
@@ -72,8 +93,8 @@ describe Fridge::AccessToken do
|
|
|
72
93
|
end
|
|
73
94
|
|
|
74
95
|
it 'should represent :exp in seconds since the epoch' do
|
|
75
|
-
hash = JWT.decode(subject.serialize, public_key)
|
|
76
|
-
expect(hash['exp']).to be_a
|
|
96
|
+
hash, = JWT.decode(subject.serialize, public_key)
|
|
97
|
+
expect(hash['exp']).to be_a Integer
|
|
77
98
|
end
|
|
78
99
|
|
|
79
100
|
it 'should be deterministic' do
|
|
@@ -93,12 +114,43 @@ describe Fridge::AccessToken do
|
|
|
93
114
|
|
|
94
115
|
expect(copy.attributes[:foo]).to eq 'bar'
|
|
95
116
|
expect(copy.foo).to eq 'bar'
|
|
117
|
+
expect(copy.respond_to?(:foo)).to be_truthy
|
|
118
|
+
expect(copy.respond_to?(:bar)).to be_falsey
|
|
96
119
|
end
|
|
97
120
|
|
|
98
121
|
it 'should raise an error if required attributes are missing' do
|
|
99
122
|
subject.subject = nil
|
|
100
123
|
expect { subject.serialize }.to raise_error Fridge::SerializationError
|
|
101
124
|
end
|
|
125
|
+
|
|
126
|
+
it 'should encode and decode :actor as :act' do
|
|
127
|
+
# The `act` field can recursively encode additional
|
|
128
|
+
# claims, so we check those too.
|
|
129
|
+
actor = { subject: 'foo', username: 'test', actor: { subject: 'bar' } }
|
|
130
|
+
subject = described_class.new(options.merge(actor: actor))
|
|
131
|
+
|
|
132
|
+
# The JWT lib will return everything as strings, so we'll
|
|
133
|
+
# test that, although eventually we'll want to see symbols back.
|
|
134
|
+
actor_s = { 'sub' => 'foo', 'username' => 'test',
|
|
135
|
+
'act' => { 'sub' => 'bar' } }
|
|
136
|
+
hash, = JWT.decode(subject.serialize, public_key)
|
|
137
|
+
expect(hash['act']).to eq(actor_s)
|
|
138
|
+
|
|
139
|
+
# Now, check that we properly get symbols back
|
|
140
|
+
new = described_class.new(subject.serialize)
|
|
141
|
+
expect(new.actor).to eq(actor)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should be idempotent' do
|
|
145
|
+
subject = described_class.new(options)
|
|
146
|
+
expect(subject.serialize).to eq(subject.serialize)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'should be idempotent with an actor' do
|
|
150
|
+
actor = { subject: 'foo', username: 'test', actor: { subject: 'bar' } }
|
|
151
|
+
subject = described_class.new(options.merge(actor: actor))
|
|
152
|
+
expect(subject.serialize).to eq(subject.serialize)
|
|
153
|
+
end
|
|
102
154
|
end
|
|
103
155
|
|
|
104
156
|
describe '#expired?' do
|
|
@@ -1,218 +1,219 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'fixtures/app'
|
|
3
|
-
require 'fixtures/controller'
|
|
4
|
-
require 'rspec/rails'
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
context Fridge::RailsHelpers do
|
|
9
|
-
let(:organization_url) do
|
|
10
|
-
"https://auth.aptible.com/users/#{SecureRandom.uuid}"
|
|
11
|
-
end
|
|
12
|
-
let(:private_key) { OpenSSL::PKey::RSA.new(1024) }
|
|
13
|
-
let(:public_key) { OpenSSL::PKey::RSA.new(private_key.public_key) }
|
|
4
|
+
describe Fridge::RailsHelpers do
|
|
5
|
+
include RSpec::Rails::ControllerExampleGroup
|
|
14
6
|
|
|
15
|
-
|
|
16
|
-
{
|
|
17
|
-
subject: "https://auth.aptible.com/users/#{SecureRandom.uuid}",
|
|
18
|
-
expires_at: Time.now + 3600
|
|
19
|
-
}
|
|
20
|
-
end
|
|
21
|
-
let(:access_token) { Fridge::AccessToken.new(options) }
|
|
7
|
+
controller(ActionController::Base) { include Fridge::RailsHelpers }
|
|
22
8
|
|
|
23
|
-
|
|
9
|
+
let(:organization_url) do
|
|
10
|
+
"https://auth.aptible.com/users/#{SecureRandom.uuid}"
|
|
11
|
+
end
|
|
12
|
+
let(:private_key) { OpenSSL::PKey::RSA.new(1024) }
|
|
13
|
+
let(:public_key) { OpenSSL::PKey::RSA.new(private_key.public_key) }
|
|
14
|
+
|
|
15
|
+
let(:options) do
|
|
16
|
+
{
|
|
17
|
+
subject: "https://auth.aptible.com/users/#{SecureRandom.uuid}",
|
|
18
|
+
expires_at: Time.now + 3600
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
let(:access_token) { Fridge::AccessToken.new(options) }
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
before { Fridge.configuration.public_key = public_key.to_s }
|
|
23
|
+
let(:cookies) { controller.send(:cookies) }
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
request.env['HTTP_AUTHORIZATION'] = 'Bearer foobar'
|
|
31
|
-
expect(controller.bearer_token).to eq 'foobar'
|
|
32
|
-
end
|
|
25
|
+
before { Fridge.configuration.private_key = private_key.to_s }
|
|
26
|
+
before { Fridge.configuration.public_key = public_key.to_s }
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
describe '#bearer_token' do
|
|
29
|
+
it 'returns the bearer token from the Authorization: header' do
|
|
30
|
+
request.env['HTTP_AUTHORIZATION'] = 'Bearer foobar'
|
|
31
|
+
expect(controller.bearer_token).to eq 'foobar'
|
|
38
32
|
end
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
it 'returns nil in the absence of an Authorization: header' do
|
|
35
|
+
request.env['HTTP_AUTHORIZATION'] = nil
|
|
36
|
+
expect(controller.bearer_token).to be_nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
describe '#token_subject' do
|
|
41
|
+
it 'returns the subject encoded in the token' do
|
|
42
|
+
controller.stub(:current_token) { access_token }
|
|
43
|
+
expect(controller.token_subject).to eq access_token.subject
|
|
50
44
|
end
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
it 'returns nil if no token is present' do
|
|
47
|
+
controller.stub(:current_token) { nil }
|
|
48
|
+
expect(controller.token_subject).to be_nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
describe '#token_scope' do
|
|
53
|
+
it 'returns the scope encoded in the token' do
|
|
54
|
+
controller.stub(:current_token) { access_token }
|
|
55
|
+
expect(controller.token_scope).to eq access_token.scope
|
|
62
56
|
end
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
it 'returns nil if no token is present' do
|
|
59
|
+
controller.stub(:current_token) { nil }
|
|
60
|
+
expect(controller.token_scope).to be_nil
|
|
61
|
+
end
|
|
62
|
+
end
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
expect { controller.current_token }.to raise_error Fridge::InvalidToken
|
|
70
|
-
end
|
|
64
|
+
describe '#current_token' do
|
|
65
|
+
before { controller.stub(:bearer_token) { access_token.serialize } }
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
it 'should raise an error if the token is not a valid JWT' do
|
|
68
|
+
controller.stub(:bearer_token) { 'foobar' }
|
|
69
|
+
expect { controller.current_token }.to raise_error Fridge::InvalidToken
|
|
70
|
+
end
|
|
76
71
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
it 'should raise an error if the token has expired' do
|
|
73
|
+
access_token.expires_at = Time.now - 3600
|
|
74
|
+
expect { controller.current_token }.to raise_error Fridge::InvalidToken
|
|
75
|
+
end
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
it 'should raise an error if custom validation fails' do
|
|
78
|
+
Fridge.configuration.validator = ->(_) { false }
|
|
79
|
+
expect { controller.current_token }.to raise_error Fridge::InvalidToken
|
|
80
|
+
end
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
end
|
|
82
|
+
it 'should not raise an error if a valid token is passed' do
|
|
83
|
+
expect { controller.current_token }.not_to raise_error
|
|
89
84
|
end
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
end
|
|
86
|
+
it 'should return the token if a valid token is passed' do
|
|
87
|
+
expect(controller.current_token.id).to eq access_token.id
|
|
88
|
+
end
|
|
89
|
+
end
|
|
96
90
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
describe '#session_subject' do
|
|
92
|
+
it 'returns the subject encoded in the session' do
|
|
93
|
+
controller.stub(:session_token) { access_token }
|
|
94
|
+
expect(controller.session_subject).to eq access_token.subject
|
|
101
95
|
end
|
|
102
96
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
end
|
|
97
|
+
it 'returns nil if no session is present' do
|
|
98
|
+
controller.stub(:session_token) { nil }
|
|
99
|
+
expect(controller.session_subject).to be_nil
|
|
100
|
+
end
|
|
101
|
+
end
|
|
109
102
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
103
|
+
describe '#session_token' do
|
|
104
|
+
it 'should delete all cookies on error' do
|
|
105
|
+
cookies[:fridge_session] = 'foobar'
|
|
106
|
+
controller.session_token
|
|
107
|
+
expect(cookies.deleted?(:fridge_session, domain: 'auth.aptible.com'))
|
|
108
|
+
.to be true
|
|
109
|
+
end
|
|
114
110
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
it 'should return nil on error' do
|
|
112
|
+
cookies[:fridge_session] = 'foobar'
|
|
113
|
+
expect(controller.session_token).to be_nil
|
|
114
|
+
end
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
it 'should return the token stored in :fridge_session' do
|
|
117
|
+
cookies[:fridge_session] = access_token.serialize
|
|
118
|
+
expect(controller.session_token.id).to eq access_token.id
|
|
119
|
+
end
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
expect(controller.session_token.scope).to eq 'read'
|
|
126
|
-
end
|
|
121
|
+
context 'with a non-:read scope' do
|
|
122
|
+
before { options.merge!(scope: 'manage') }
|
|
127
123
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
end
|
|
124
|
+
it 'should downgrade the token' do
|
|
125
|
+
cookies[:fridge_session] = access_token.serialize
|
|
126
|
+
expect(controller.session_token.scope).to eq 'read'
|
|
132
127
|
end
|
|
133
|
-
end
|
|
134
128
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
expect(controller.validate_token(access_token)).to be_false
|
|
129
|
+
it 'should not change the validity of a token' do
|
|
130
|
+
cookies[:fridge_session] = access_token.serialize
|
|
131
|
+
expect(controller.session_token).to be_valid
|
|
139
132
|
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
140
135
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
136
|
+
describe '#validate_token' do
|
|
137
|
+
it 'should return false if the token is invalid' do
|
|
138
|
+
Fridge.configuration.validator = ->(_) { false }
|
|
139
|
+
expect(controller.validate_token(access_token)).to be false
|
|
140
|
+
end
|
|
145
141
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
end
|
|
142
|
+
it 'should return false if the token validator fails' do
|
|
143
|
+
Fridge.configuration.validator = ->(_) { raise 'Foobar' }
|
|
144
|
+
expect(controller.validate_token(access_token)).to be false
|
|
150
145
|
end
|
|
151
146
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
147
|
+
it 'should return the token if valid' do
|
|
148
|
+
Fridge.configuration.validator = ->(_) { true }
|
|
149
|
+
expect(controller.validate_token(access_token)).to eq access_token
|
|
150
|
+
end
|
|
151
|
+
end
|
|
157
152
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
153
|
+
describe '#validate_token' do
|
|
154
|
+
it 'should raise an exception if the token is invalid' do
|
|
155
|
+
Fridge.configuration.validator = ->(_) { false }
|
|
156
|
+
expect { controller.validate_token!(access_token) }
|
|
157
|
+
.to raise_error Fridge::InvalidToken
|
|
162
158
|
end
|
|
163
159
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
controller.sessionize_token(access_token)
|
|
168
|
-
expect(cookies[:fridge_session]).to eq access_token.serialize
|
|
169
|
-
end
|
|
160
|
+
it 'should return the token if valid' do
|
|
161
|
+
Fridge.configuration.validator = ->(_) { true }
|
|
162
|
+
expect(controller.validate_token!(access_token)).to eq access_token
|
|
170
163
|
end
|
|
164
|
+
end
|
|
171
165
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
166
|
+
describe '#sessionize_token' do
|
|
167
|
+
it 'should set a session cookie' do
|
|
168
|
+
Rails.stub_chain(:env, :development?) { false }
|
|
169
|
+
controller.sessionize_token(access_token)
|
|
170
|
+
expect(cookies[:fridge_session]).to eq access_token.serialize
|
|
177
171
|
end
|
|
172
|
+
end
|
|
178
173
|
|
|
179
|
-
|
|
180
|
-
|
|
174
|
+
describe '#fridge_cookie_name' do
|
|
175
|
+
it 'is configurable' do
|
|
176
|
+
Fridge.configuration.cookie_name = 'foobar'
|
|
177
|
+
expect(controller.fridge_cookie_name).to eq 'foobar'
|
|
178
|
+
end
|
|
179
|
+
end
|
|
181
180
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
181
|
+
describe '#write_shared_cookie' do
|
|
182
|
+
before { Rails.stub_chain(:env, :development?) { false } }
|
|
183
|
+
|
|
184
|
+
it 'should save cookie' do
|
|
185
|
+
controller.write_shared_cookie(:organization_url, organization_url)
|
|
186
|
+
expect(cookies[:organization_url]).to eq organization_url
|
|
186
187
|
end
|
|
188
|
+
end
|
|
187
189
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
end
|
|
190
|
+
describe '#read_shared_cookie' do
|
|
191
|
+
it 'should read cookie' do
|
|
192
|
+
cookies[:organization_url] = { value: organization_url }
|
|
193
|
+
expect(controller.read_shared_cookie(:organization_url)).to(
|
|
194
|
+
eq organization_url
|
|
195
|
+
)
|
|
195
196
|
end
|
|
197
|
+
end
|
|
196
198
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
describe '#delete_shared_cookie' do
|
|
200
|
+
before { Rails.stub_chain(:env, :development?) { false } }
|
|
199
201
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
end
|
|
202
|
+
it 'should delete cookie' do
|
|
203
|
+
controller.write_shared_cookie(:organization_url, organization_url)
|
|
204
|
+
controller.delete_shared_cookie(:organization_url)
|
|
205
|
+
expect(cookies[:organization_url]).to be_nil
|
|
205
206
|
end
|
|
207
|
+
end
|
|
206
208
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
describe '#fridge_cookie_options' do
|
|
210
|
+
before { Rails.stub_chain(:env, :development?) { false } }
|
|
209
211
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
end
|
|
212
|
+
it 'are configurable' do
|
|
213
|
+
Fridge.configuration.cookie_options = { foobar: true }
|
|
214
|
+
options = controller.fridge_cookie_options
|
|
215
|
+
expect(options[:domain]).to eq 'auth.aptible.com'
|
|
216
|
+
expect(options[:foobar]).to eq true
|
|
216
217
|
end
|
|
217
218
|
end
|
|
218
219
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
3
3
|
|
|
4
|
+
require 'active_support/all'
|
|
5
|
+
require 'action_controller'
|
|
6
|
+
require 'action_dispatch'
|
|
7
|
+
require 'action_view'
|
|
8
|
+
|
|
9
|
+
require 'fridge'
|
|
10
|
+
require 'fridge/rails_helpers'
|
|
11
|
+
|
|
12
|
+
require 'rspec'
|
|
13
|
+
require 'rspec/rails'
|
|
14
|
+
|
|
4
15
|
# Load shared spec files
|
|
5
16
|
Dir["#{File.dirname(__FILE__)}/shared/**/*.rb"].each do |file|
|
|
6
17
|
require file
|
|
7
18
|
end
|
|
8
19
|
|
|
9
|
-
# Require library up front
|
|
10
|
-
require 'fridge'
|
|
11
|
-
|
|
12
20
|
RSpec.configure do |config|
|
|
13
21
|
config.before { Fridge.configuration.reset }
|
|
14
22
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fridge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Frank Macreery
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-01-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: gem_config
|
|
@@ -30,14 +30,28 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 1.5.6
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 1.5.6
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: aptible-tasks
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: bundler
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -53,7 +67,7 @@ dependencies:
|
|
|
53
67
|
- !ruby/object:Gem::Version
|
|
54
68
|
version: '1.5'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
70
|
+
name: pry
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
58
72
|
requirements:
|
|
59
73
|
- - ">="
|
|
@@ -67,7 +81,7 @@ dependencies:
|
|
|
67
81
|
- !ruby/object:Gem::Version
|
|
68
82
|
version: '0'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
84
|
+
name: rails
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
72
86
|
requirements:
|
|
73
87
|
- - ">="
|
|
@@ -81,7 +95,7 @@ dependencies:
|
|
|
81
95
|
- !ruby/object:Gem::Version
|
|
82
96
|
version: '0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
98
|
+
name: rake
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
86
100
|
requirements:
|
|
87
101
|
- - ">="
|
|
@@ -100,14 +114,14 @@ dependencies:
|
|
|
100
114
|
requirements:
|
|
101
115
|
- - "~>"
|
|
102
116
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '
|
|
117
|
+
version: '3.0'
|
|
104
118
|
type: :development
|
|
105
119
|
prerelease: false
|
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
121
|
requirements:
|
|
108
122
|
- - "~>"
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '
|
|
124
|
+
version: '3.0'
|
|
111
125
|
- !ruby/object:Gem::Dependency
|
|
112
126
|
name: rspec-rails
|
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -122,20 +136,6 @@ dependencies:
|
|
|
122
136
|
- - ">="
|
|
123
137
|
- !ruby/object:Gem::Version
|
|
124
138
|
version: '0'
|
|
125
|
-
- !ruby/object:Gem::Dependency
|
|
126
|
-
name: pry
|
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - ">="
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: '0'
|
|
132
|
-
type: :development
|
|
133
|
-
prerelease: false
|
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - ">="
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: '0'
|
|
139
139
|
description: Token validation for distributed resource servers
|
|
140
140
|
email:
|
|
141
141
|
- frank@macreery.com
|
|
@@ -143,6 +143,7 @@ executables: []
|
|
|
143
143
|
extensions: []
|
|
144
144
|
extra_rdoc_files: []
|
|
145
145
|
files:
|
|
146
|
+
- ".github/CODEOWNERS"
|
|
146
147
|
- ".gitignore"
|
|
147
148
|
- ".rspec"
|
|
148
149
|
- ".travis.yml"
|
|
@@ -153,13 +154,13 @@ files:
|
|
|
153
154
|
- fridge.gemspec
|
|
154
155
|
- lib/fridge.rb
|
|
155
156
|
- lib/fridge/access_token.rb
|
|
157
|
+
- lib/fridge/expired_token.rb
|
|
156
158
|
- lib/fridge/invalid_token.rb
|
|
157
159
|
- lib/fridge/rails_helpers.rb
|
|
158
160
|
- lib/fridge/railtie.rb
|
|
159
161
|
- lib/fridge/serialization_error.rb
|
|
160
162
|
- lib/fridge/version.rb
|
|
161
163
|
- spec/fixtures/app.rb
|
|
162
|
-
- spec/fixtures/controller.rb
|
|
163
164
|
- spec/fridge/access_token_spec.rb
|
|
164
165
|
- spec/fridge/rails_helpers_spec.rb
|
|
165
166
|
- spec/spec_helper.rb
|
|
@@ -167,7 +168,7 @@ homepage: https://github.com/aptible/fridge
|
|
|
167
168
|
licenses:
|
|
168
169
|
- MIT
|
|
169
170
|
metadata: {}
|
|
170
|
-
post_install_message:
|
|
171
|
+
post_install_message:
|
|
171
172
|
rdoc_options: []
|
|
172
173
|
require_paths:
|
|
173
174
|
- lib
|
|
@@ -182,14 +183,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
182
183
|
- !ruby/object:Gem::Version
|
|
183
184
|
version: '0'
|
|
184
185
|
requirements: []
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
signing_key:
|
|
186
|
+
rubygems_version: 3.0.3
|
|
187
|
+
signing_key:
|
|
188
188
|
specification_version: 4
|
|
189
189
|
summary: Token validation for distributed resource servers
|
|
190
190
|
test_files:
|
|
191
191
|
- spec/fixtures/app.rb
|
|
192
|
-
- spec/fixtures/controller.rb
|
|
193
192
|
- spec/fridge/access_token_spec.rb
|
|
194
193
|
- spec/fridge/rails_helpers_spec.rb
|
|
195
194
|
- spec/spec_helper.rb
|