fridge 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 14721d992f4d97d606aa10ea94c061553328292f
4
+ data.tar.gz: 377c3b2543822ebdeea357a4e9ead8bd45ca4938
5
+ SHA512:
6
+ metadata.gz: 556a8a8805c2402d1accabe75bcc860a23659f528eaca8cf84868c12524ff0893312e6ef3b02e418705c4bdfe7601a3ab75d68ead2df8fa74b00d07624016cd8
7
+ data.tar.gz: 33936c9085ebf03959a4a7a6d6ad7d8d53377e3899e3008e56191ef401c1cf3da9a0edbe2799cfdd3e417ae30cc64d5b222a03167348c94251004851728ee532
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - jruby
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fridge.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Aptible, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # ![](https://raw.github.com/aptible/straptible/master/lib/straptible/rails/templates/public.api/icon-60px.png) Fridge
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/fridge.png)](https://rubygems.org/gems/fridge)
4
+ [![Build Status](https://travis-ci.org/aptible/fridge.png?branch=master)](https://travis-ci.org/aptible/fridge)
5
+ [![Dependency Status](https://gemnasium.com/aptible/fridge.png)](https://gemnasium.com/aptible/fridge)
6
+
7
+ Token validation for distributed resource servers.
8
+
9
+ ## Installation
10
+
11
+ Add the following line to your application's Gemfile.
12
+
13
+ gem 'fridge'
14
+
15
+ And then run `bundle install`.
16
+
17
+ ## Usage
18
+
19
+ ### Configuration
20
+
21
+ | Parameter | Description | Possible Values |
22
+ | --------- | ----------- | --------------- |
23
+ | `private_key` | Private token signing key | A PEM-formatted key |
24
+ | `public_key` | Public token verification key (the private key's complement) | A PEM-formatted key |
25
+ | `signing_algorithm` | Algorithm to use for sigining and verification | `RS512`, `RS256` |
26
+ | `validator` | A lambda used to perform custom validation of tokens | Any `Proc` |
27
+
28
+ Resource servers must configure a public key corresponding to an authorization server, in order to verify tokens issued by that server. Authorization servers must configure a private key.
29
+
30
+ By default, public key-verified tokens are considered valid if and only iff they have not expired (i.e., `expires_at > Time.now`). However, some applications may want to perform additional validations. (For example, an authorization server may allow online revocation of tokens before their natural expiration, and need to check the current ). This is possible by configuring a custom validator:
31
+
32
+ ```ruby
33
+ Fridge.configure do |config|
34
+ config.validator = lambda do |access_token|
35
+ token = Token.find_by(id: access_token.id)
36
+ token && !token.revoked?
37
+ end
38
+ end
39
+ ```
40
+
41
+ The validator will be called with a single argument, the `Fridge::AccessToken` instance.
42
+
43
+ ### Integrating with Fridge from a resource server
44
+
45
+ From any of your controllers, you may access the following methods:
46
+
47
+ * `current_token`: The `Fridge::AccessToken` passed via `Authorization` header.
48
+ * `token_subject`: The subject (`:sub`) of the current token.
49
+ * `token_scope`: The scope (`:scope`) of the current token.
50
+ * `session_token`: The `Fridge::AccessToken` stored in the user agent's cookies.
51
+ * `session_subject`: The subject (`:sub`) of the current session token.
52
+
53
+
54
+ ### Integrating with Fridge from an authorization server
55
+
56
+ A Fridge access token may be constructed a la the following example:
57
+
58
+ ```ruby
59
+ access_token = Fridge::AccessToken.new(
60
+ id: '0f1aa5ce-6e93-4812-b3fc-3b7f7b685991',
61
+ subject: 'https://auth.aptible.com/users/e600a449-b308-4162-ac28-8a2769ad3f05',
62
+ expires_at: 1.hour.from_now
63
+ )
64
+ ```
65
+
66
+ The only required hash parameters are `:subject` and `:expires_at`. Additionally, you may specify `:id`, `:scope` and `issuer`. To set this token in a cookie that's readable across your entire domain, you may invoke the following command from any Rails controller:
67
+
68
+ ```ruby
69
+ store_session_cookie(access_token)
70
+ ```
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork the project.
75
+ 1. Commit your changes, with specs.
76
+ 1. Ensure that your code passes specs (`rake spec`) and meets Aptible's Ruby style guide (`rake rubocop`).
77
+ 1. Create a new pull request on GitHub.
78
+
79
+ ## Copyright and License
80
+
81
+ MIT License, see [LICENSE](LICENSE.md) for details.
82
+
83
+ Copyright (c) 2014 [Aptible](https://www.aptible.com), Frank Macreery, and contributors.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'aptible/tasks'
4
+ Aptible::Tasks.load_tasks
data/fridge.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'English'
6
+ require 'fridge/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'fridge'
10
+ spec.version = Fridge::VERSION
11
+ spec.authors = ['Frank Macreery']
12
+ spec.email = ['frank@macreery.com']
13
+ spec.description = %q{Token validation for distributed resource servers}
14
+ spec.summary = %q{Token validation for distributed resource servers}
15
+ spec.homepage = 'https://github.com/aptible/fridge'
16
+ spec.license = 'MIT'
17
+
18
+ spec.files = `git ls-files`.split($RS)
19
+ spec.test_files = spec.files.grep(/^spec\//)
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'gem_config'
23
+ spec.add_dependency 'jwt'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.5'
26
+ spec.add_development_dependency 'aptible-tasks'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rails'
29
+ spec.add_development_dependency 'rspec', '~> 2.0'
30
+ spec.add_development_dependency 'rspec-rails'
31
+ spec.add_development_dependency 'pry'
32
+ end
@@ -0,0 +1,102 @@
1
+ require 'jwt'
2
+
3
+ module Fridge
4
+ class AccessToken
5
+ attr_accessor :id, :issuer, :subject, :scope, :expires_at
6
+
7
+ def initialize(jwt_or_options = nil)
8
+ options = case jwt_or_options
9
+ when String
10
+ validate_public_key!
11
+ decode_and_verify(jwt_or_options)
12
+ when Hash then jwt_or_options
13
+ else {}
14
+ end
15
+ options.each do |key, value|
16
+ instance_variable_set("@#{key}", value)
17
+ end
18
+ end
19
+
20
+ def serialize
21
+ validate_parameters!
22
+ validate_private_key!
23
+ encode_and_sign
24
+ end
25
+
26
+ def encode_and_sign
27
+ JWT.encode({
28
+ id: id,
29
+ iss: issuer,
30
+ sub: subject,
31
+ scope: scope,
32
+ exp: expires_at.to_i
33
+ }, private_key, algorithm)
34
+ rescue
35
+ raise SerializationError, 'Invalid private key or signing algorithm'
36
+ end
37
+
38
+ def decode_and_verify(jwt)
39
+ hash = JWT.decode(jwt, public_key)
40
+ {
41
+ id: hash['id'],
42
+ issuer: hash['iss'],
43
+ subject: hash['sub'],
44
+ scope: hash['scope'],
45
+ expires_at: Time.at(hash['exp'])
46
+ }
47
+ rescue JWT::DecodeError
48
+ raise InvalidToken, 'Invalid access token'
49
+ end
50
+
51
+ def valid?
52
+ !expired?
53
+ end
54
+
55
+ def expired?
56
+ expires_at.nil? || expires_at < Time.now
57
+ end
58
+
59
+ def private_key
60
+ return unless config.private_key
61
+ @private_key ||= OpenSSL::PKey::RSA.new(config.private_key)
62
+ rescue
63
+ nil
64
+ end
65
+
66
+ def public_key
67
+ if config.private_key
68
+ @public_key ||= OpenSSL::PKey::RSA.new(config.private_key).public_key
69
+ elsif config.public_key
70
+ @public_key ||= OpenSSL::PKey::RSA.new(config.public_key)
71
+ end
72
+ rescue
73
+ nil
74
+ end
75
+
76
+ def algorithm
77
+ config.signing_algorithm
78
+ end
79
+
80
+ def config
81
+ Fridge.configuration
82
+ end
83
+
84
+ protected
85
+
86
+ def validate_parameters!
87
+ [:subject, :expires_at].each do |attribute|
88
+ unless send(attribute)
89
+ fail SerializationError, "Missing attribute: #{attribute}"
90
+ end
91
+ end
92
+ end
93
+
94
+ def validate_private_key!
95
+ fail SerializationError, 'No private key configured' unless private_key
96
+ end
97
+
98
+ def validate_public_key!
99
+ fail SerializationError, 'No public key configured' unless public_key
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,4 @@
1
+ module Fridge
2
+ class InvalidToken < StandardError
3
+ end
4
+ end
@@ -0,0 +1,63 @@
1
+ module Fridge
2
+ module RailsHelpers
3
+ def token_scope
4
+ current_token.scope if current_token
5
+ end
6
+
7
+ def token_subject
8
+ current_token.subject if current_token
9
+ end
10
+
11
+ def current_token
12
+ return unless bearer_token
13
+ @current_token ||= AccessToken.new(bearer_token).tap do |token|
14
+ validate_token!(token)
15
+ end
16
+ end
17
+
18
+ def bearer_token
19
+ header = request.env['HTTP_AUTHORIZATION']
20
+ header.gsub(/^Bearer /, '') unless header.nil?
21
+ end
22
+
23
+ def session_subject
24
+ session_token.subject if session_token
25
+ end
26
+
27
+ def session_token
28
+ return unless cookies[:session_token]
29
+ @session_token = AccessToken.new(cookies[:session_token]).tap do |token|
30
+ validate_token!(token)
31
+ end
32
+ rescue
33
+ clear_session_token
34
+ @session_token = nil
35
+ end
36
+
37
+ def validate_token!(access_token)
38
+ validator = Fridge.configuration.validator
39
+ fail InvalidToken unless validator.call(access_token)
40
+ end
41
+
42
+ def store_session_token(access_token)
43
+ # Ensure that any cookie-persisted tokens are read-only
44
+ access_token.scope = 'read'
45
+
46
+ jwt = access_token.serialize
47
+ cookies[:session_token] = cookie_options.merge(
48
+ value: jwt,
49
+ expires_at: access_token.expires_at
50
+ )
51
+ end
52
+
53
+ def clear_session_token
54
+ cookies.delete :session_token, domain: :all
55
+ nil
56
+ end
57
+
58
+ def cookie_options
59
+ secure = !Rails.env.development?
60
+ { domain: :all, secure: secure, httponly: true }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ require 'fridge/rails_helpers'
2
+
3
+ module Fridge
4
+ class Railtie < Rails::Railtie
5
+ initializer 'fridge.rails_helpers' do
6
+ ActionController::Base.send :include, RailsHelpers
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module Fridge
2
+ class SerializationError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module Fridge
2
+ VERSION = '0.1.0'
3
+ end
data/lib/fridge.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'gem_config'
2
+
3
+ require 'fridge/version'
4
+ require 'fridge/access_token'
5
+ require 'fridge/serialization_error'
6
+ require 'fridge/invalid_token'
7
+
8
+ require 'fridge/railtie' if defined?(Rails)
9
+
10
+ module Fridge
11
+ include GemConfig::Base
12
+
13
+ with_configuration do
14
+ has :private_key, classes: [String]
15
+ has :public_key, classes: [String]
16
+
17
+ has :signing_algorithm, values: %w(RS512 RS256), default: 'RS512'
18
+
19
+ # A validator must raise an exception or return a false value for an
20
+ # invalid token
21
+ has :validator, classes: [Proc],
22
+ default: -> (access_token) { access_token.valid? }
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'active_support/all'
2
+ require 'action_controller'
3
+ require 'action_dispatch'
4
+
5
+ module Rails
6
+ class App
7
+ def env_config
8
+ {}
9
+ end
10
+
11
+ def routes
12
+ return @routes if defined?(@routes)
13
+ @routes = ActionDispatch::Routing::RouteSet.new
14
+ @routes.draw do
15
+ resources :posts
16
+ end
17
+ @routes
18
+ end
19
+ end
20
+
21
+ def self.application
22
+ @app ||= App.new
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ require 'fridge/rails_helpers'
2
+
3
+ class Controller < ActionController::Base
4
+ include Fridge::RailsHelpers
5
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fridge::AccessToken do
4
+ describe '#initialize' do
5
+ let(:private_key) { OpenSSL::PKey::RSA.new(1024) }
6
+ let(:public_key) { OpenSSL::PKey::RSA.new(private_key.public_key) }
7
+
8
+ before { Fridge.configuration.public_key = public_key.to_s }
9
+
10
+ it 'should accept a hash' do
11
+ access_token = described_class.new(id: 'foobar')
12
+ expect(access_token.id).to eq 'foobar'
13
+ end
14
+
15
+ it 'should accept a JWT' do
16
+ jwt = JWT.encode({ id: 'foobar', exp: 0 }, private_key, 'RS512')
17
+ access_token = described_class.new(jwt)
18
+ expect(access_token.id).to eq 'foobar'
19
+ end
20
+
21
+ it 'should raise an error on an invalid JWT' do
22
+ expect { described_class.new('foobar') }.to raise_error
23
+ end
24
+
25
+ it 'should raise an error on an incorrectly signed JWT' do
26
+ jwt = JWT.encode({ id: 'foobar' }, OpenSSL::PKey::RSA.new(1024), 'RS512')
27
+ expect { described_class.new(jwt) }.to raise_error Fridge::InvalidToken
28
+ end
29
+ end
30
+
31
+ describe '#serialize' do
32
+ let(:options) do
33
+ {
34
+ id: SecureRandom.uuid,
35
+ iss: 'https://auth.aptible.com',
36
+ subject: "https://auth.aptible.com/users/#{SecureRandom.uuid}",
37
+ scope: 'read',
38
+ expires_at: Time.now + 3600
39
+ }
40
+ end
41
+
42
+ let(:private_key) { OpenSSL::PKey::RSA.new(1024) }
43
+ let(:public_key) { OpenSSL::PKey::RSA.new(private_key.public_key) }
44
+
45
+ before { Fridge.configuration.private_key = private_key.to_s }
46
+
47
+ subject { described_class.new(options) }
48
+
49
+ it 'should return a JWT comprised of token attributes' do
50
+ expect(subject.serialize).to eq JWT.encode({
51
+ id: subject.id,
52
+ iss: subject.issuer,
53
+ sub: subject.subject,
54
+ scope: subject.scope,
55
+ exp: subject.expires_at.to_i
56
+ }, private_key, 'RS512')
57
+ end
58
+
59
+ it 'should be verifiable with the application public key' do
60
+ expect { JWT.decode(subject.serialize, public_key) }.not_to raise_error
61
+ end
62
+
63
+ it 'should be tamper-resistant' do
64
+ header, _, signature = subject.serialize.split('.')
65
+ tampered_claim = JWT.base64url_encode({ foo: 'bar' }.to_json)
66
+ tampered_token = [header, tampered_claim, signature].join('.')
67
+
68
+ expect do
69
+ JWT.decode(tampered_token, public_key)
70
+ end.to raise_error JWT::DecodeError
71
+ end
72
+
73
+ it 'should represent :exp in seconds since the epoch' do
74
+ hash = JWT.decode(subject.serialize, public_key)
75
+ expect(hash['exp']).to be_a Fixnum
76
+ end
77
+
78
+ it 'should be deterministic' do
79
+ expect(subject.serialize).to eq subject.serialize
80
+ end
81
+
82
+ it 'should complement #initialize' do
83
+ copy = described_class.new(subject.serialize)
84
+ expect(copy.subject).to eq subject.subject
85
+ expect(copy.expires_at.to_i).to eq subject.expires_at.to_i
86
+ expect(copy.scope).to eq subject.scope
87
+ end
88
+
89
+ it 'should raise an error if required attributes are missing' do
90
+ subject.subject = nil
91
+ expect { subject.serialize }.to raise_error Fridge::SerializationError
92
+ end
93
+ end
94
+
95
+ describe '#expired?' do
96
+ it 'should return true if the access token has expired' do
97
+ subject.stub(:expires_at) { Time.now - 3600 }
98
+ expect(subject).to be_expired
99
+ end
100
+
101
+ it 'should return true if the access token has no expiration set' do
102
+ subject.stub(:expires_at) { nil }
103
+ expect(subject).to be_expired
104
+ end
105
+
106
+ it 'should return false otherwise' do
107
+ subject.stub(:expires_at) { Time.now + 3600 }
108
+ expect(subject).not_to be_expired
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/app'
3
+ require 'fixtures/controller'
4
+ require 'rspec/rails'
5
+
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(:private_key) { OpenSSL::PKey::RSA.new(1024) }
10
+ let(:public_key) { OpenSSL::PKey::RSA.new(private_key.public_key) }
11
+
12
+ let(:options) do
13
+ {
14
+ subject: "https://auth.aptible.com/users/#{SecureRandom.uuid}",
15
+ expires_at: Time.now + 3600
16
+ }
17
+ end
18
+ let(:access_token) { Fridge::AccessToken.new(options) }
19
+
20
+ let(:cookies) { controller.send(:cookies) }
21
+
22
+ before { Fridge.configuration.private_key = private_key.to_s }
23
+ before { Fridge.configuration.public_key = public_key.to_s }
24
+
25
+ describe '#bearer_token' do
26
+ it 'returns the bearer token from the Authorization: header' do
27
+ request.env['HTTP_AUTHORIZATION'] = 'Bearer foobar'
28
+ expect(controller.bearer_token).to eq 'foobar'
29
+ end
30
+
31
+ it 'returns nil in the absence of an Authorization: header' do
32
+ request.env['HTTP_AUTHORIZATION'] = nil
33
+ expect(controller.bearer_token).to be_nil
34
+ end
35
+ end
36
+
37
+ describe '#token_subject' do
38
+ it 'returns the subject encoded in the token' do
39
+ controller.stub(:current_token) { access_token }
40
+ expect(controller.token_subject).to eq access_token.subject
41
+ end
42
+
43
+ it 'returns nil if no token is present' do
44
+ controller.stub(:current_token) { nil }
45
+ expect(controller.token_subject).to be_nil
46
+ end
47
+ end
48
+
49
+ describe '#token_scope' do
50
+ it 'returns the scope encoded in the token' do
51
+ controller.stub(:current_token) { access_token }
52
+ expect(controller.token_scope).to eq access_token.scope
53
+ end
54
+
55
+ it 'returns nil if no token is present' do
56
+ controller.stub(:current_token) { nil }
57
+ expect(controller.token_scope).to be_nil
58
+ end
59
+ end
60
+
61
+ describe '#current_token' do
62
+ before { controller.stub(:bearer_token) { access_token.serialize } }
63
+
64
+ it 'should raise an error if the token is not a valid JWT' do
65
+ controller.stub(:bearer_token) { 'foobar' }
66
+ expect { controller.current_token }.to raise_error Fridge::InvalidToken
67
+ end
68
+
69
+ it 'should raise an error if the token has expired' do
70
+ access_token.expires_at = Time.now - 3600
71
+ expect { controller.current_token }.to raise_error Fridge::InvalidToken
72
+ end
73
+
74
+ it 'should raise an error if custom validation fails' do
75
+ Fridge.configuration.validator = -> (token) { false }
76
+ expect { controller.current_token }.to raise_error Fridge::InvalidToken
77
+ end
78
+
79
+ it 'should not raise an error if a valid token is passed' do
80
+ expect { controller.current_token }.not_to raise_error
81
+ end
82
+
83
+ it 'should return the token if a valid token is passed' do
84
+ expect(controller.current_token.id).to eq access_token.id
85
+ end
86
+ end
87
+
88
+ describe '#session_subject' do
89
+ it 'returns the subject encoded in the session' do
90
+ controller.stub(:session_token) { access_token }
91
+ expect(controller.session_subject).to eq access_token.subject
92
+ end
93
+
94
+ it 'returns nil if no session is present' do
95
+ controller.stub(:session_token) { nil }
96
+ expect(controller.session_subject).to be_nil
97
+ end
98
+ end
99
+
100
+ describe '#session_token' do
101
+ it 'should delete all cookies on error' do
102
+ cookies[:session_token] = 'foobar'
103
+ controller.session_token
104
+ expect(cookies.deleted?(:session_token, domain: :all)).to be_true
105
+ end
106
+
107
+ it 'should return nil on error' do
108
+ cookies[:session_token] = 'foobar'
109
+ expect(controller.session_token).to be_nil
110
+ end
111
+
112
+ it 'should return the token stored in :session_token' do
113
+ cookies[:session_token] = access_token.serialize
114
+ expect(controller.session_token.id).to eq access_token.id
115
+ end
116
+ end
117
+
118
+ describe '#store_session_token' do
119
+ it 'should set a session cookie' do
120
+ Rails.stub_chain(:env, :development?) { false }
121
+ controller.store_session_token(access_token)
122
+ expect(cookies[:session_token]).to eq access_token.serialize
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ # Load shared spec files
5
+ Dir["#{File.dirname(__FILE__)}/shared/**/*.rb"].each do |file|
6
+ require file
7
+ end
8
+
9
+ # Require library up front
10
+ require 'fridge'
11
+
12
+ RSpec.configure do |config|
13
+ config.before { Fridge.configuration.reset }
14
+ end
metadata ADDED
@@ -0,0 +1,195 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fridge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Frank Macreery
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gem_config
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jwt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aptible-tasks
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-rails
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ 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
+ description: Token validation for distributed resource servers
140
+ email:
141
+ - frank@macreery.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - .gitignore
147
+ - .rspec
148
+ - .travis.yml
149
+ - Gemfile
150
+ - LICENSE.md
151
+ - README.md
152
+ - Rakefile
153
+ - fridge.gemspec
154
+ - lib/fridge.rb
155
+ - lib/fridge/access_token.rb
156
+ - lib/fridge/invalid_token.rb
157
+ - lib/fridge/rails_helpers.rb
158
+ - lib/fridge/railtie.rb
159
+ - lib/fridge/serialization_error.rb
160
+ - lib/fridge/version.rb
161
+ - spec/fixtures/app.rb
162
+ - spec/fixtures/controller.rb
163
+ - spec/fridge/access_token_spec.rb
164
+ - spec/fridge/rails_helpers_spec.rb
165
+ - spec/spec_helper.rb
166
+ homepage: https://github.com/aptible/fridge
167
+ licenses:
168
+ - MIT
169
+ metadata: {}
170
+ post_install_message:
171
+ rdoc_options: []
172
+ require_paths:
173
+ - lib
174
+ required_ruby_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - '>='
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ requirements: []
185
+ rubyforge_project:
186
+ rubygems_version: 2.2.1
187
+ signing_key:
188
+ specification_version: 4
189
+ summary: Token validation for distributed resource servers
190
+ test_files:
191
+ - spec/fixtures/app.rb
192
+ - spec/fixtures/controller.rb
193
+ - spec/fridge/access_token_spec.rb
194
+ - spec/fridge/rails_helpers_spec.rb
195
+ - spec/spec_helper.rb