fridge 0.3.1 → 0.4.4

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