fridge 0.3.1 → 0.4.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 28164c99b4a71e24796559da6b1fc0663d0f42c9
4
- data.tar.gz: db5603732b2c608dd063cdf0b3c8e6cf33f8ead6
2
+ SHA256:
3
+ metadata.gz: f2d340550f97b33c430967cef5b8de4a59b73acfdd5a1ce62ad3ee7d17a6f8c9
4
+ data.tar.gz: 06a758734a6b6e668043c3bffe2cf350495325dfdab4f73948e2788f97d5c89d
5
5
  SHA512:
6
- metadata.gz: 44f92c7854c7d359fe5cf9596b165c9ff93815f9f1d0040782f2b230de38a47ea314aed24bc48ed531d4fffb880dacd0cbaa85c83261f8739f0b17b5727245e4
7
- data.tar.gz: 2fbf80cfddbade814f62fb21e9492f393d155a5df6e55e49ebf310ee5a4c5218382277d473c518f1b93b7978e592a7edaeac213fc7f0e5d57db3aa48309451c1
6
+ metadata.gz: d8b53167a69aaf39d60b4abbe6ad347968efddc1b2333dc12136b730600d65ab0c72fc8c7416d190b33fc55ce3571d8b98cbf1322c7a0eddd46c46517114cc0c
7
+ data.tar.gz: 0632f0de72e4654663256000e201568745697a05170e49191d31598a9a5bd2f6158871379253bee1302d3b10ebf76c5a6b84d2baae803cf8fd935bb4324a47b3
@@ -0,0 +1 @@
1
+ * @dawenster
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  sudo: false
2
2
  rvm:
3
- - 2.0.0
4
- - jruby
3
+ - 2.2
4
+ - 2.5
5
+ - 2.6
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'activesupport', '~> 4.0'
4
+ gem 'nokogiri', '~> 1.9.1'
5
+
3
6
  # Specify your gem's dependencies in fridge.gemspec
4
7
  gemspec
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) 2014 [Aptible](https://www.aptible.com) and contributors.
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
 
@@ -20,13 +21,13 @@ Gem::Specification.new do |spec|
20
21
  spec.require_paths = ['lib']
21
22
 
22
23
  spec.add_dependency 'gem_config'
23
- spec.add_dependency 'jwt', '~> 0.1.13'
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 'rake'
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 'rspec', '~> 2.0'
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
- has :signing_algorithm, values: %w(RS512 RS256), default: 'RS512'
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
@@ -5,7 +5,6 @@ module Fridge
5
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
@@ -21,7 +20,6 @@ module Fridge
21
20
  end
22
21
  self.attributes = options
23
22
  end
24
- # rubocop:enable MethodLength
25
23
 
26
24
  def to_s
27
25
  serialize
@@ -29,6 +27,7 @@ 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
@@ -42,18 +41,18 @@ module Fridge
42
41
  h.merge!(attributes)
43
42
  h = encode_for_jwt(h)
44
43
  JWT.encode(h, private_key, algorithm)
45
- rescue
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
- hash = JWT.decode(jwt, public_key)
52
- decode_from_jwt(hash)
53
- rescue JWT::DecodeError
54
- 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
55
55
  end
56
- # rubocop:enable MethodLength
57
56
 
58
57
  def downgrade
59
58
  self.scope = 'read'
@@ -69,8 +68,9 @@ module Fridge
69
68
 
70
69
  def private_key
71
70
  return unless config.private_key
71
+
72
72
  @private_key ||= OpenSSL::PKey::RSA.new(config.private_key)
73
- rescue
73
+ rescue StandardError
74
74
  nil
75
75
  end
76
76
 
@@ -80,7 +80,7 @@ module Fridge
80
80
  elsif config.public_key
81
81
  @public_key ||= OpenSSL::PKey::RSA.new(config.public_key)
82
82
  end
83
- rescue
83
+ rescue StandardError
84
84
  nil
85
85
  end
86
86
 
@@ -102,19 +102,24 @@ module Fridge
102
102
  end
103
103
  end
104
104
 
105
+ def respond_to_missing?(method, include_private = false)
106
+ attributes.key?(method) || super
107
+ end
108
+
105
109
  def validate_parameters!
106
110
  [:subject, :expires_at].each do |attribute|
107
111
  next if send(attribute)
108
- fail SerializationError, "Missing attribute: #{attribute}"
112
+
113
+ raise SerializationError, "Missing attribute: #{attribute}"
109
114
  end
110
115
  end
111
116
 
112
117
  def validate_private_key!
113
- fail SerializationError, 'No private key configured' unless private_key
118
+ raise SerializationError, 'No private key configured' unless private_key
114
119
  end
115
120
 
116
121
  def validate_public_key!
117
- fail SerializationError, 'No public key configured' unless public_key
122
+ raise SerializationError, 'No public key configured' unless public_key
118
123
  end
119
124
 
120
125
  # Internally, we use "subject" to refer to "sub", and so on. We also
@@ -122,6 +127,8 @@ module Fridge
122
127
  # mapping from Fridge to JWT and vice-versa.
123
128
 
124
129
  def encode_for_jwt(hash)
130
+ hash = hash.dup
131
+
125
132
  out = {
126
133
  id: hash.delete(:id),
127
134
  iss: hash.delete(:issuer),
@@ -143,6 +150,8 @@ module Fridge
143
150
  end
144
151
 
145
152
  def decode_from_jwt(hash)
153
+ hash = hash.dup
154
+
146
155
  out = {
147
156
  id: hash.delete('id'),
148
157
  issuer: hash.delete('iss'),
@@ -0,0 +1,4 @@
1
+ module Fridge
2
+ class ExpiredToken < InvalidToken
3
+ end
4
+ end
@@ -21,6 +21,7 @@ module Fridge
21
21
 
22
22
  def current_token
23
23
  return unless bearer_token
24
+
24
25
  @current_token ||= AccessToken.new(bearer_token).tap do |token|
25
26
  validate_token!(token)
26
27
  end
@@ -41,10 +42,11 @@ module Fridge
41
42
 
42
43
  def session_token
43
44
  return unless session_cookie
45
+
44
46
  @session_token ||= AccessToken.new(session_cookie).tap do |token|
45
47
  validate_token!(token).downgrade
46
48
  end
47
- rescue
49
+ rescue StandardError
48
50
  clear_session_cookie
49
51
  end
50
52
 
@@ -52,7 +54,7 @@ module Fridge
52
54
  def validate_token(access_token)
53
55
  validator = Fridge.configuration.validator
54
56
  validator.call(access_token) && access_token
55
- rescue
57
+ rescue StandardError
56
58
  false
57
59
  end
58
60
 
@@ -62,7 +64,7 @@ module Fridge
62
64
  if validator.call(access_token)
63
65
  access_token
64
66
  else
65
- fail InvalidToken
67
+ raise InvalidToken, 'Rejected by validator'
66
68
  end
67
69
  end
68
70
 
@@ -86,12 +88,12 @@ module Fridge
86
88
  end
87
89
 
88
90
  def clear_session_cookie
89
- cookies.delete fridge_cookie_name, domain: :all
91
+ cookies.delete fridge_cookie_name, domain: auth_domain
90
92
  nil
91
93
  end
92
94
 
93
95
  def write_shared_cookie(name, value, options = {})
94
- fail 'Can only write string cookie values' unless value.is_a?(String)
96
+ raise 'Can only write string cookie values' unless value.is_a?(String)
95
97
 
96
98
  cookies[name] = {
97
99
  value: value,
@@ -103,9 +105,10 @@ module Fridge
103
105
  cookies[name]
104
106
  end
105
107
 
106
- def fetch_shared_cookie(name, &block)
108
+ def fetch_shared_cookie(name)
107
109
  return read_shared_cookie(name) if read_shared_cookie(name)
108
- write_shared_cookie(block.call)
110
+
111
+ write_shared_cookie(yield)
109
112
  end
110
113
 
111
114
  def delete_shared_cookie(name)
@@ -118,8 +121,18 @@ module Fridge
118
121
 
119
122
  def fridge_cookie_options
120
123
  secure = !Rails.env.development?
121
- options = { domain: :all, secure: secure, httponly: true }
124
+ options = { domain: auth_domain, secure: secure, httponly: true }
122
125
  options.merge(Fridge.configuration.cookie_options)
123
126
  end
127
+
128
+ def auth_domain
129
+ domain = URI.parse(Aptible::Auth.configuration.root_url).host
130
+
131
+ # On localhost we fall back to the default setting b/c browsers won't set
132
+ # cookies if localhost is named
133
+ domain == 'localhost' ? :all : domain
134
+ rescue StandardError
135
+ 'auth.aptible.com'
136
+ end
124
137
  end
125
138
  end
@@ -1,3 +1,3 @@
1
1
  module Fridge
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.4'.freeze
3
3
  end
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
- @app ||= App.new
19
+ @application ||= App.new
23
20
  end
24
21
  end
@@ -14,13 +14,17 @@ describe Fridge::AccessToken do
14
14
  end
15
15
 
16
16
  it 'should accept a JWT' do
17
- jwt = JWT.encode({ id: 'foobar', exp: 0 }, private_key, 'RS512')
17
+ jwt = JWT.encode(
18
+ { id: 'foobar', exp: Time.now.to_i + 10 },
19
+ private_key, 'RS512'
20
+ )
18
21
  access_token = described_class.new(jwt)
19
22
  expect(access_token.id).to eq 'foobar'
20
23
  end
21
24
 
22
25
  it 'should raise an error on an invalid JWT' do
23
- expect { described_class.new('foobar') }.to raise_error
26
+ expect { described_class.new('foobar') }
27
+ .to raise_error Fridge::InvalidToken
24
28
  end
25
29
 
26
30
  it 'should raise an error on an incorrectly signed JWT' do
@@ -28,11 +32,19 @@ describe Fridge::AccessToken do
28
32
  expect { described_class.new(jwt) }.to raise_error Fridge::InvalidToken
29
33
  end
30
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
+
31
43
  # http://bit.ly/jwt-none-vulnerability
32
44
  it 'should raise an error with { "alg": "none" }' do
33
45
  jwt = "#{Base64.encode64({ typ: 'JWT', alg: 'none' }.to_json).chomp}." \
34
46
  "#{Base64.encode64({ id: 'foobar' }.to_json).chomp}"
35
- expect(JWT.decode(jwt, nil, false)).to eq('id' => 'foobar')
47
+ expect(JWT.decode(jwt, nil, false)[0]).to eq('id' => 'foobar')
36
48
  expect { described_class.new(jwt) }.to raise_error Fridge::InvalidToken
37
49
  end
38
50
  end
@@ -81,8 +93,8 @@ describe Fridge::AccessToken do
81
93
  end
82
94
 
83
95
  it 'should represent :exp in seconds since the epoch' do
84
- hash = JWT.decode(subject.serialize, public_key)
85
- expect(hash['exp']).to be_a Fixnum
96
+ hash, = JWT.decode(subject.serialize, public_key)
97
+ expect(hash['exp']).to be_a Integer
86
98
  end
87
99
 
88
100
  it 'should be deterministic' do
@@ -102,6 +114,8 @@ describe Fridge::AccessToken do
102
114
 
103
115
  expect(copy.attributes[:foo]).to eq 'bar'
104
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
105
119
  end
106
120
 
107
121
  it 'should raise an error if required attributes are missing' do
@@ -119,13 +133,24 @@ describe Fridge::AccessToken do
119
133
  # test that, although eventually we'll want to see symbols back.
120
134
  actor_s = { 'sub' => 'foo', 'username' => 'test',
121
135
  'act' => { 'sub' => 'bar' } }
122
- hash = JWT.decode(subject.serialize, public_key)
136
+ hash, = JWT.decode(subject.serialize, public_key)
123
137
  expect(hash['act']).to eq(actor_s)
124
138
 
125
139
  # Now, check that we properly get symbols back
126
140
  new = described_class.new(subject.serialize)
127
141
  expect(new.actor).to eq(actor)
128
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
129
154
  end
130
155
 
131
156
  describe '#expired?' do
@@ -1,218 +1,239 @@
1
1
  require 'spec_helper'
2
2
  require 'fixtures/app'
3
- require 'fixtures/controller'
4
- require 'rspec/rails'
5
3
 
6
- # http://say26.com/rspec-testing-controllers-outside-of-a-rails-application
7
- describe Controller, type: :controller do
8
- context Fridge::RailsHelpers do
9
- let(:organization_url) do
10
- "https://auth.aptible.com/users/#{SecureRandom.uuid}"
4
+ describe Fridge::RailsHelpers do
5
+ include RSpec::Rails::ControllerExampleGroup
6
+
7
+ controller(ActionController::Base) { include Fridge::RailsHelpers }
8
+
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) }
22
+
23
+ let(:cookies) { controller.send(:cookies) }
24
+
25
+ before { Fridge.configuration.private_key = private_key.to_s }
26
+ before { Fridge.configuration.public_key = public_key.to_s }
27
+
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'
11
32
  end
12
- let(:private_key) { OpenSSL::PKey::RSA.new(1024) }
13
- let(:public_key) { OpenSSL::PKey::RSA.new(private_key.public_key) }
14
33
 
15
- let(:options) do
16
- {
17
- subject: "https://auth.aptible.com/users/#{SecureRandom.uuid}",
18
- expires_at: Time.now + 3600
19
- }
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
20
37
  end
21
- let(:access_token) { Fridge::AccessToken.new(options) }
38
+ end
22
39
 
23
- let(:cookies) { controller.send(:cookies) }
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
44
+ end
24
45
 
25
- before { Fridge.configuration.private_key = private_key.to_s }
26
- before { Fridge.configuration.public_key = public_key.to_s }
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
27
51
 
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'
32
- end
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
56
+ end
33
57
 
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
58
+ it 'returns nil if no token is present' do
59
+ controller.stub(:current_token) { nil }
60
+ expect(controller.token_scope).to be_nil
38
61
  end
62
+ end
39
63
 
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
44
- end
64
+ describe '#current_token' do
65
+ before { controller.stub(:bearer_token) { access_token.serialize } }
45
66
 
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
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
50
70
  end
51
71
 
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
56
- end
57
-
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
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
62
75
  end
63
76
 
64
- describe '#current_token' do
65
- before { controller.stub(:bearer_token) { access_token.serialize } }
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
66
81
 
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
82
+ it 'should not raise an error if a valid token is passed' do
83
+ expect { controller.current_token }.not_to raise_error
84
+ end
71
85
 
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
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
76
90
 
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
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
95
+ end
81
96
 
82
- it 'should not raise an error if a valid token is passed' do
83
- expect { controller.current_token }.not_to raise_error
84
- 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
85
102
 
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
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
89
109
  end
90
110
 
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
95
- end
111
+ it 'should return nil on error' do
112
+ cookies[:fridge_session] = 'foobar'
113
+ expect(controller.session_token).to be_nil
114
+ end
96
115
 
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
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
101
119
  end
102
120
 
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: :all)).to be true
108
- end
121
+ context 'with a non-:read scope' do
122
+ before { options.merge!(scope: 'manage') }
109
123
 
110
- it 'should return nil on error' do
111
- cookies[:fridge_session] = 'foobar'
112
- expect(controller.session_token).to be_nil
124
+ it 'should downgrade the token' do
125
+ cookies[:fridge_session] = access_token.serialize
126
+ expect(controller.session_token.scope).to eq 'read'
113
127
  end
114
128
 
115
- it 'should return the token stored in :fridge_session' do
129
+ it 'should not change the validity of a token' do
116
130
  cookies[:fridge_session] = access_token.serialize
117
- expect(controller.session_token.id).to eq access_token.id
131
+ expect(controller.session_token).to be_valid
118
132
  end
133
+ end
134
+ end
119
135
 
120
- context 'with a non-:read scope' do
121
- before { options.merge!(scope: 'manage') }
122
-
123
- it 'should downgrade the token' do
124
- cookies[:fridge_session] = access_token.serialize
125
- expect(controller.session_token.scope).to eq 'read'
126
- end
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
127
141
 
128
- it 'should not change the validity of a token' do
129
- cookies[:fridge_session] = access_token.serialize
130
- expect(controller.session_token).to be_valid
131
- end
132
- 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
133
145
  end
134
146
 
135
- describe '#validate_token' do
136
- it 'should return false if the token is invalid' do
137
- Fridge.configuration.validator = ->(_) { false }
138
- expect(controller.validate_token(access_token)).to be false
139
- end
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
140
152
 
141
- it 'should return false if the token validator fails' do
142
- Fridge.configuration.validator = ->(_) { fail 'Foobar' }
143
- expect(controller.validate_token(access_token)).to be false
144
- end
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
158
+ end
145
159
 
146
- it 'should return the token if valid' do
147
- Fridge.configuration.validator = ->(_) { true }
148
- expect(controller.validate_token(access_token)).to eq access_token
149
- 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
150
163
  end
164
+ end
151
165
 
152
- describe '#validate_token' do
153
- it 'should raise an exception if the token is invalid' do
154
- Fridge.configuration.validator = ->(_) { false }
155
- expect { controller.validate_token!(access_token) }.to raise_error
156
- end
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
171
+ end
172
+ end
157
173
 
158
- it 'should return the token if valid' do
159
- Fridge.configuration.validator = ->(_) { true }
160
- expect(controller.validate_token!(access_token)).to eq access_token
161
- end
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'
162
178
  end
179
+ end
163
180
 
164
- describe '#sessionize_token' do
165
- it 'should set a session cookie' do
166
- Rails.stub_chain(:env, :development?) { false }
167
- controller.sessionize_token(access_token)
168
- expect(cookies[:fridge_session]).to eq access_token.serialize
169
- end
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
170
187
  end
188
+ end
171
189
 
172
- describe '#fridge_cookie_name' do
173
- it 'is configurable' do
174
- Fridge.configuration.cookie_name = 'foobar'
175
- expect(controller.fridge_cookie_name).to eq 'foobar'
176
- 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
+ )
177
196
  end
197
+ end
178
198
 
179
- describe '#write_shared_cookie' do
180
- before { Rails.stub_chain(:env, :development?) { false } }
199
+ describe '#delete_shared_cookie' do
200
+ before { Rails.stub_chain(:env, :development?) { false } }
181
201
 
182
- it 'should save cookie' do
183
- controller.write_shared_cookie(:organization_url, organization_url)
184
- expect(cookies[:organization_url]).to eq organization_url
185
- 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
186
206
  end
207
+ end
187
208
 
188
- describe '#read_shared_cookie' do
189
- it 'should read cookie' do
190
- cookies[:organization_url] = { value: organization_url }
191
- expect(controller.read_shared_cookie(:organization_url)).to(
192
- eq organization_url
193
- )
194
- end
195
- end
209
+ describe '#fridge_cookie_options' do
210
+ before { Rails.stub_chain(:env, :development?) { false } }
196
211
 
197
- describe '#delete_shared_cookie' do
198
- before { Rails.stub_chain(:env, :development?) { false } }
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
217
+ end
199
218
 
200
- it 'should delete cookie' do
201
- controller.write_shared_cookie(:organization_url, organization_url)
202
- controller.delete_shared_cookie(:organization_url)
203
- expect(cookies[:organization_url]).to be_nil
219
+ it 'restricts cookies to the specific subdomain' do
220
+ auth = class_double('Aptible::Auth').as_stubbed_const
221
+ allow(auth).to receive_message_chain(:configuration, :root_url) do
222
+ 'https://auth-bob.aptible-sandbox.com'
204
223
  end
205
- end
206
224
 
207
- describe '#fridge_cookie_options' do
208
- before { Rails.stub_chain(:env, :development?) { false } }
225
+ options = controller.fridge_cookie_options
226
+ expect(options[:domain]).to eq 'auth-bob.aptible-sandbox.com'
227
+ end
209
228
 
210
- it 'are configurable' do
211
- Fridge.configuration.cookie_options = { foobar: true }
212
- options = controller.fridge_cookie_options
213
- expect(options[:domain]).to eq :all
214
- expect(options[:foobar]).to eq true
229
+ it 'handles local development using defaults' do
230
+ auth = class_double('Aptible::Auth').as_stubbed_const
231
+ allow(auth).to receive_message_chain(:configuration, :root_url) do
232
+ 'https://localhost:4000'
215
233
  end
234
+
235
+ options = controller.fridge_cookie_options
236
+ expect(options[:domain]).to eq :all
216
237
  end
217
238
  end
218
239
  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.1
4
+ version: 0.4.4
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: 2016-03-01 00:00:00.000000000 Z
11
+ date: 2021-05-18 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: 0.1.13
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: 0.1.13
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: aptible-tasks
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: rake
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: rails
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: '2.0'
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: '2.0'
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
- rubyforge_project:
186
- rubygems_version: 2.4.5.1
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
@@ -1,5 +0,0 @@
1
- require 'fridge/rails_helpers'
2
-
3
- class Controller < ActionController::Base
4
- include Fridge::RailsHelpers
5
- end