fridge 0.1.2 → 0.2.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/fridge/access_token.rb +26 -12
- data/lib/fridge/rails_helpers.rb +38 -13
- data/lib/fridge/version.rb +1 -1
- data/lib/fridge.rb +3 -0
- data/spec/fridge/access_token_spec.rb +9 -1
- data/spec/fridge/rails_helpers_spec.rb +55 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b49455bd0f488a16a7644a83d79f3c4cbb5d71b6
|
4
|
+
data.tar.gz: c778c54e88438ef63194d90304860710026bc403
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9cea20d8b86972656d086f046ddc8d0248215116200a3bbf2bb5b2b916919bd973b90bc8781325ffbb51e36079ad77396711508c44824ec252a76ae2223211c9
|
7
|
+
data.tar.gz: 7d12fc628282bc7fb2910b0148c55e0a98186ca423b6bf34c2bea4ae8f33e59b5ee89df0755ce7c1c46ba8869b3bee9e368de09f3e06117fd02befc38c130c8b
|
data/lib/fridge/access_token.rb
CHANGED
@@ -2,7 +2,8 @@ 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,
|
6
|
+
:jwt, :attributes
|
6
7
|
|
7
8
|
# rubocop:disable MethodLength
|
8
9
|
def initialize(jwt_or_options = nil)
|
@@ -14,9 +15,11 @@ module Fridge
|
|
14
15
|
when Hash then jwt_or_options
|
15
16
|
else {}
|
16
17
|
end
|
17
|
-
|
18
|
-
|
18
|
+
[:id, :issuer, :subject, :scope, :expires_at].each do |key|
|
19
|
+
send "#{key}=", options.delete(key)
|
19
20
|
end
|
21
|
+
self.attributes = options.reject { |k, v| v.nil? }
|
22
|
+
attributes.symbolize_keys!
|
20
23
|
end
|
21
24
|
# rubocop:enable MethodLength
|
22
25
|
|
@@ -38,23 +41,26 @@ module Fridge
|
|
38
41
|
sub: subject,
|
39
42
|
scope: scope,
|
40
43
|
exp: expires_at.to_i
|
41
|
-
}, private_key, algorithm)
|
44
|
+
}.merge(attributes), private_key, algorithm)
|
42
45
|
rescue
|
43
46
|
raise SerializationError, 'Invalid private key or signing algorithm'
|
44
47
|
end
|
45
48
|
|
49
|
+
# rubocop:disable MethodLength
|
46
50
|
def decode_and_verify(jwt)
|
47
51
|
hash = JWT.decode(jwt, public_key)
|
48
|
-
{
|
49
|
-
id: hash
|
50
|
-
issuer: hash
|
51
|
-
subject: hash
|
52
|
-
scope: hash
|
53
|
-
expires_at: Time.at(hash
|
52
|
+
base = {
|
53
|
+
id: hash.delete('id'),
|
54
|
+
issuer: hash.delete('iss'),
|
55
|
+
subject: hash.delete('sub'),
|
56
|
+
scope: hash.delete('scope'),
|
57
|
+
expires_at: Time.at(hash.delete('exp'))
|
54
58
|
}
|
55
|
-
|
56
|
-
|
59
|
+
base.merge(hash)
|
60
|
+
rescue JWT::DecodeError
|
61
|
+
raise InvalidToken, 'Invalid access token'
|
57
62
|
end
|
63
|
+
# rubocop:enable MethodLength
|
58
64
|
|
59
65
|
def valid?
|
60
66
|
!expired?
|
@@ -91,6 +97,14 @@ module Fridge
|
|
91
97
|
|
92
98
|
protected
|
93
99
|
|
100
|
+
def method_missing(method, *args, &block)
|
101
|
+
if attributes.key?(method)
|
102
|
+
attributes[method]
|
103
|
+
else
|
104
|
+
super
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
94
108
|
def validate_parameters!
|
95
109
|
[:subject, :expires_at].each do |attribute|
|
96
110
|
unless send(attribute)
|
data/lib/fridge/rails_helpers.rb
CHANGED
@@ -25,39 +25,64 @@ module Fridge
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def session_token
|
28
|
-
return unless
|
29
|
-
@session_token
|
28
|
+
return unless session_cookie
|
29
|
+
@session_token ||= AccessToken.new(session_cookie).tap do |token|
|
30
30
|
validate_token!(token)
|
31
31
|
end
|
32
32
|
rescue
|
33
|
-
|
34
|
-
@session_token = nil
|
33
|
+
clear_session_cookie
|
35
34
|
end
|
36
35
|
|
36
|
+
# Validates token, and returns the token, or nil
|
37
|
+
def validate_token(access_token)
|
38
|
+
validator = Fridge.configuration.validator
|
39
|
+
validator.call(access_token) && access_token
|
40
|
+
rescue
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
# Validates token, and raises an exception if invalid
|
37
45
|
def validate_token!(access_token)
|
38
46
|
validator = Fridge.configuration.validator
|
39
|
-
|
47
|
+
if validator.call(access_token)
|
48
|
+
access_token
|
49
|
+
else
|
50
|
+
fail InvalidToken
|
51
|
+
end
|
40
52
|
end
|
41
53
|
|
42
|
-
def
|
54
|
+
def sessionize_token(access_token)
|
43
55
|
# Ensure that any cookie-persisted tokens are read-only
|
44
56
|
access_token.scope = 'read'
|
45
57
|
|
46
58
|
jwt = access_token.serialize
|
47
|
-
|
59
|
+
self.session_cookie = {
|
48
60
|
value: jwt,
|
49
|
-
|
50
|
-
)
|
61
|
+
expires: access_token.expires_at
|
62
|
+
}.merge(fridge_cookie_options)
|
51
63
|
end
|
52
64
|
|
53
|
-
def
|
54
|
-
cookies
|
65
|
+
def session_cookie
|
66
|
+
cookies[fridge_cookie_name]
|
67
|
+
end
|
68
|
+
|
69
|
+
def session_cookie=(cookie)
|
70
|
+
cookies[fridge_cookie_name] = cookie
|
71
|
+
end
|
72
|
+
|
73
|
+
def clear_session_cookie
|
74
|
+
cookies.delete fridge_cookie_name, domain: :all
|
55
75
|
nil
|
56
76
|
end
|
57
77
|
|
58
|
-
def
|
78
|
+
def fridge_cookie_name
|
79
|
+
Fridge.configuration.cookie_name
|
80
|
+
end
|
81
|
+
|
82
|
+
def fridge_cookie_options
|
59
83
|
secure = !Rails.env.development?
|
60
|
-
{ domain: :all, secure: secure, httponly: true }
|
84
|
+
options = { domain: :all, secure: secure, httponly: true }
|
85
|
+
options.merge(Fridge.configuration.cookie_options)
|
61
86
|
end
|
62
87
|
end
|
63
88
|
end
|
data/lib/fridge/version.rb
CHANGED
data/lib/fridge.rb
CHANGED
@@ -19,5 +19,8 @@ module Fridge
|
|
19
19
|
# A validator must raise an exception or return a false value for an
|
20
20
|
# invalid token
|
21
21
|
has :validator, classes: [Proc], default: ->(token) { token.valid? }
|
22
|
+
|
23
|
+
has :cookie_name, classes: [String, Symbol], default: :fridge_session
|
24
|
+
has :cookie_options, classes: [Hash], default: {}
|
22
25
|
end
|
23
26
|
end
|
@@ -32,7 +32,7 @@ describe Fridge::AccessToken do
|
|
32
32
|
let(:options) do
|
33
33
|
{
|
34
34
|
id: SecureRandom.uuid,
|
35
|
-
|
35
|
+
issuer: 'https://auth.aptible.com',
|
36
36
|
subject: "https://auth.aptible.com/users/#{SecureRandom.uuid}",
|
37
37
|
scope: 'read',
|
38
38
|
expires_at: Time.now + 3600
|
@@ -86,6 +86,14 @@ describe Fridge::AccessToken do
|
|
86
86
|
expect(copy.scope).to eq subject.scope
|
87
87
|
end
|
88
88
|
|
89
|
+
it 'should include custom attributes' do
|
90
|
+
subject = described_class.new(options.merge(foo: 'bar'))
|
91
|
+
copy = described_class.new(subject.serialize)
|
92
|
+
|
93
|
+
expect(copy.attributes[:foo]).to eq 'bar'
|
94
|
+
expect(copy.foo).to eq 'bar'
|
95
|
+
end
|
96
|
+
|
89
97
|
it 'should raise an error if required attributes are missing' do
|
90
98
|
subject.subject = nil
|
91
99
|
expect { subject.serialize }.to raise_error Fridge::SerializationError
|
@@ -99,27 +99,74 @@ describe Controller, type: :controller do
|
|
99
99
|
|
100
100
|
describe '#session_token' do
|
101
101
|
it 'should delete all cookies on error' do
|
102
|
-
cookies[:
|
102
|
+
cookies[:fridge_session] = 'foobar'
|
103
103
|
controller.session_token
|
104
|
-
expect(cookies.deleted?(:
|
104
|
+
expect(cookies.deleted?(:fridge_session, domain: :all)).to be_true
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'should return nil on error' do
|
108
|
-
cookies[:
|
108
|
+
cookies[:fridge_session] = 'foobar'
|
109
109
|
expect(controller.session_token).to be_nil
|
110
110
|
end
|
111
111
|
|
112
|
-
it 'should return the token stored in :
|
113
|
-
cookies[:
|
112
|
+
it 'should return the token stored in :fridge_session' do
|
113
|
+
cookies[:fridge_session] = access_token.serialize
|
114
114
|
expect(controller.session_token.id).to eq access_token.id
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
describe '#
|
118
|
+
describe '#validate_token' do
|
119
|
+
it 'should return false if the token is invalid' do
|
120
|
+
Fridge.configuration.validator = ->(token) { false }
|
121
|
+
expect(controller.validate_token(access_token)).to be_false
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should return false if the token validator fails' do
|
125
|
+
Fridge.configuration.validator = ->(token) { fail 'Foobar' }
|
126
|
+
expect(controller.validate_token(access_token)).to be_false
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return the token if valid' do
|
130
|
+
Fridge.configuration.validator = ->(token) { true }
|
131
|
+
expect(controller.validate_token(access_token)).to eq access_token
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#validate_token' do
|
136
|
+
it 'should raise an exception if the token is invalid' do
|
137
|
+
Fridge.configuration.validator = ->(token) { false }
|
138
|
+
expect { controller.validate_token!(access_token) }.to raise_error
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should return the token if valid' do
|
142
|
+
Fridge.configuration.validator = ->(token) { true }
|
143
|
+
expect(controller.validate_token!(access_token)).to eq access_token
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#sessionize_token' do
|
119
148
|
it 'should set a session cookie' do
|
120
149
|
Rails.stub_chain(:env, :development?) { false }
|
121
|
-
controller.
|
122
|
-
expect(cookies[:
|
150
|
+
controller.sessionize_token(access_token)
|
151
|
+
expect(cookies[:fridge_session]).to eq access_token.serialize
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#fridge_cookie_name' do
|
156
|
+
it 'is configurable' do
|
157
|
+
Fridge.configuration.cookie_name = 'foobar'
|
158
|
+
expect(controller.fridge_cookie_name).to eq 'foobar'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#fridge_cookie_options' do
|
163
|
+
before { Rails.stub_chain(:env, :development?) { false } }
|
164
|
+
|
165
|
+
it 'are configurable' do
|
166
|
+
Fridge.configuration.cookie_options = { foobar: true }
|
167
|
+
options = controller.fridge_cookie_options
|
168
|
+
expect(options[:domain]).to eq :all
|
169
|
+
expect(options[:foobar]).to eq true
|
123
170
|
end
|
124
171
|
end
|
125
172
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Macreery
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_config
|