openid-token-proxy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +4 -0
  7. data/Guardfile +41 -0
  8. data/LICENSE.md +22 -0
  9. data/README.md +211 -0
  10. data/Rakefile +16 -0
  11. data/app/controllers/openid_token_proxy/application_controller.rb +4 -0
  12. data/app/controllers/openid_token_proxy/callback_controller.rb +22 -0
  13. data/config/initializers/inflections.rb +3 -0
  14. data/config/routes.rb +3 -0
  15. data/docs/diagrams.sketch +0 -0
  16. data/docs/openid-token-proxy-flow.png +0 -0
  17. data/docs/regular-openid-flow.png +0 -0
  18. data/lib/openid-token-proxy.rb +1 -0
  19. data/lib/openid_token_proxy/client.rb +48 -0
  20. data/lib/openid_token_proxy/config.rb +56 -0
  21. data/lib/openid_token_proxy/engine.rb +5 -0
  22. data/lib/openid_token_proxy/error.rb +7 -0
  23. data/lib/openid_token_proxy/token/authentication.rb +54 -0
  24. data/lib/openid_token_proxy/token/expired.rb +12 -0
  25. data/lib/openid_token_proxy/token/invalid_application.rb +12 -0
  26. data/lib/openid_token_proxy/token/invalid_audience.rb +12 -0
  27. data/lib/openid_token_proxy/token/invalid_issuer.rb +12 -0
  28. data/lib/openid_token_proxy/token/malformed.rb +12 -0
  29. data/lib/openid_token_proxy/token/refresh.rb +30 -0
  30. data/lib/openid_token_proxy/token/required.rb +12 -0
  31. data/lib/openid_token_proxy/token/unverifiable_signature.rb +12 -0
  32. data/lib/openid_token_proxy/token.rb +80 -0
  33. data/lib/openid_token_proxy/version.rb +3 -0
  34. data/lib/openid_token_proxy.rb +40 -0
  35. data/openid-token-proxy.gemspec +35 -0
  36. data/spec/controllers/openid_token_proxy/callback_controller_spec.rb +72 -0
  37. data/spec/dummy/README.rdoc +28 -0
  38. data/spec/dummy/Rakefile +6 -0
  39. data/spec/dummy/app/assets/images/.keep +0 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  42. data/spec/dummy/app/controllers/accounts_controller.rb +10 -0
  43. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  44. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  45. data/spec/dummy/app/controllers/home_controller.rb +7 -0
  46. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  47. data/spec/dummy/app/mailers/.keep +0 -0
  48. data/spec/dummy/app/models/.keep +0 -0
  49. data/spec/dummy/app/models/concerns/.keep +0 -0
  50. data/spec/dummy/app/views/home/index.html.erb +25 -0
  51. data/spec/dummy/app/views/layouts/application.html.erb +54 -0
  52. data/spec/dummy/bin/bundle +3 -0
  53. data/spec/dummy/bin/rails +4 -0
  54. data/spec/dummy/bin/rake +4 -0
  55. data/spec/dummy/config/application.rb +27 -0
  56. data/spec/dummy/config/boot.rb +5 -0
  57. data/spec/dummy/config/environment.rb +5 -0
  58. data/spec/dummy/config/environments/development.rb +34 -0
  59. data/spec/dummy/config/environments/production.rb +75 -0
  60. data/spec/dummy/config/environments/test.rb +39 -0
  61. data/spec/dummy/config/initializers/assets.rb +8 -0
  62. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  63. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  64. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  65. data/spec/dummy/config/initializers/inflections.rb +16 -0
  66. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  67. data/spec/dummy/config/initializers/openid.rb +5 -0
  68. data/spec/dummy/config/initializers/session_store.rb +3 -0
  69. data/spec/dummy/config/initializers/wrap_parameters.rb +9 -0
  70. data/spec/dummy/config/locales/en.yml +23 -0
  71. data/spec/dummy/config/routes.rb +5 -0
  72. data/spec/dummy/config/secrets.yml +22 -0
  73. data/spec/dummy/config.ru +4 -0
  74. data/spec/dummy/lib/assets/.keep +0 -0
  75. data/spec/dummy/log/.keep +0 -0
  76. data/spec/dummy/public/404.html +67 -0
  77. data/spec/dummy/public/422.html +67 -0
  78. data/spec/dummy/public/500.html +66 -0
  79. data/spec/dummy/public/favicon.ico +0 -0
  80. data/spec/fixtures/keys.json +26 -0
  81. data/spec/fixtures/openid-configuration.json +30 -0
  82. data/spec/lib/openid_token_proxy/client_spec.rb +150 -0
  83. data/spec/lib/openid_token_proxy/config_spec.rb +201 -0
  84. data/spec/lib/openid_token_proxy/error_spec.rb +11 -0
  85. data/spec/lib/openid_token_proxy/token/authentication_spec.rb +67 -0
  86. data/spec/lib/openid_token_proxy/token/refresh_spec.rb +71 -0
  87. data/spec/lib/openid_token_proxy/token_spec.rb +138 -0
  88. data/spec/lib/openid_token_proxy_spec.rb +38 -0
  89. data/spec/spec_helper.rb +88 -0
  90. data/spec/support/env.rb +4 -0
  91. data/spec/support/fixture.rb +3 -0
  92. metadata +359 -0
@@ -0,0 +1,201 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OpenIDTokenProxy::Config do
4
+ subject { described_class.new }
5
+ let(:with_valid_issuer) {
6
+ subject.issuer = 'https://login.windows.net/common'
7
+ subject
8
+ }
9
+
10
+ before do
11
+ stub_request(:get, "https://login.windows.net/common/.well-known/openid-configuration")
12
+ .to_return(body: fixture('openid-configuration.json'))
13
+ stub_request(:get, "https://login.windows.net/common/discovery/keys")
14
+ .to_return(body: fixture('keys.json'))
15
+ stub_request(:get, "https://example.com/.well-known/openid-configuration")
16
+ .to_return(status: 404)
17
+ end
18
+
19
+ describe '#initialize' do
20
+ it 'yields configuration to given block' do
21
+ config = described_class.new do |config|
22
+ config.client_id = 'from-block'
23
+ end
24
+ expect(config.client_id).to eq 'from-block'
25
+ end
26
+ end
27
+
28
+ describe '#client_id' do
29
+ it 'obtains its default from environment' do
30
+ stub_env('OPENID_CLIENT_ID', 'from env')
31
+ expect(subject.client_id).to eq 'from env'
32
+ end
33
+
34
+ it 'may be set explicitly' do
35
+ subject.client_id = 'overridden'
36
+ expect(subject.client_id).to eq 'overridden'
37
+ end
38
+ end
39
+
40
+ describe '#client_secret' do
41
+ it 'obtains its default from environment' do
42
+ stub_env('OPENID_CLIENT_SECRET', 'from env')
43
+ expect(subject.client_secret).to eq 'from env'
44
+ end
45
+
46
+ it 'may be set explicitly' do
47
+ subject.client_secret = 'overridden'
48
+ expect(subject.client_secret).to eq 'overridden'
49
+ end
50
+ end
51
+
52
+ describe '#issuer' do
53
+ it 'obtains its default from environment' do
54
+ stub_env('OPENID_ISSUER', 'from env')
55
+ expect(subject.issuer).to eq 'from env'
56
+ end
57
+
58
+ it 'may be overriden' do
59
+ subject.issuer = 'overridden'
60
+ expect(subject.issuer).to eq 'overridden'
61
+ end
62
+ end
63
+
64
+ describe '#redirect_uri' do
65
+ it 'obtains its default from environment' do
66
+ stub_env('OPENID_REDIRECT_URI', 'from env')
67
+ expect(subject.redirect_uri).to eq 'from env'
68
+ end
69
+
70
+ it 'may be set explicitly' do
71
+ subject.redirect_uri = 'overridden'
72
+ expect(subject.redirect_uri).to eq 'overridden'
73
+ end
74
+ end
75
+
76
+ describe '#resource' do
77
+ it 'obtains its default from environment' do
78
+ stub_env('OPENID_RESOURCE', 'from env')
79
+ expect(subject.resource).to eq 'from env'
80
+ end
81
+
82
+ it 'may be set explicitly' do
83
+ subject.resource = 'overridden'
84
+ expect(subject.resource).to eq 'overridden'
85
+ end
86
+ end
87
+
88
+ describe '#authorization_uri' do
89
+ it 'obtains its default from environment' do
90
+ stub_env('OPENID_AUTHORIZATION_URI', 'from env')
91
+ expect(subject.authorization_uri).to eq 'from env'
92
+ end
93
+
94
+ it 'may be set explicitly' do
95
+ subject.authorization_uri = 'overridden'
96
+ expect(subject.authorization_uri).to eq 'overridden'
97
+ end
98
+ end
99
+
100
+ describe '#provider_config' do
101
+ context 'when valid issuer' do
102
+ it 'loads provider configuration' do
103
+ expect do
104
+ with_valid_issuer.provider_config
105
+ end.not_to raise_error
106
+ end
107
+ end
108
+
109
+ context 'when issuer omitted' do
110
+ it 'raises' do
111
+ stub_env('OPENID_ISSUER')
112
+ expect do
113
+ subject.provider_config
114
+ end.to raise_error URI::InvalidURIError
115
+ end
116
+ end
117
+
118
+ context 'when invalid issuer' do
119
+ it 'raises' do
120
+ subject.issuer = 'https://example.com'
121
+ expect do
122
+ subject.provider_config
123
+ end.to raise_error OpenIDConnect::Discovery::DiscoveryFailed
124
+ end
125
+ end
126
+ end
127
+
128
+ describe '#authorization_endpoint' do
129
+ it 'obtains its default from environment' do
130
+ stub_env('OPENID_AUTHORIZATION_ENDPOINT', 'from env')
131
+ expect(subject.authorization_endpoint).to eq 'from env'
132
+ end
133
+
134
+ it 'may be set explicitly' do
135
+ subject.authorization_endpoint = 'overridden'
136
+ expect(subject.authorization_endpoint).to eq 'overridden'
137
+ end
138
+
139
+ context 'when not set' do
140
+ it 'defaults to endpoint from provider config' do
141
+ stub_env('OPENID_AUTHORIZATION_ENDPOINT')
142
+ ep = with_valid_issuer.authorization_endpoint
143
+ expect(ep).to eq 'https://login.windows.net/common/oauth2/authorize'
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#token_endpoint' do
149
+ it 'obtains its default from environment' do
150
+ stub_env('OPENID_TOKEN_ENDPOINT', 'from env')
151
+ expect(subject.token_endpoint).to eq 'from env'
152
+ end
153
+
154
+ it 'may be set explicitly' do
155
+ subject.token_endpoint = 'overridden'
156
+ expect(subject.token_endpoint).to eq 'overridden'
157
+ end
158
+
159
+ context 'when not set' do
160
+ it 'defaults to endpoint from provider config' do
161
+ stub_env('OPENID_TOKEN_ENDPOINT')
162
+ ep = with_valid_issuer.token_endpoint
163
+ expect(ep).to eq 'https://login.windows.net/common/oauth2/token'
164
+ end
165
+ end
166
+ end
167
+
168
+ describe '#userinfo_endpoint' do
169
+ it 'obtains its default from environment' do
170
+ stub_env('OPENID_USERINFO_ENDPOINT', 'from env')
171
+ expect(subject.userinfo_endpoint).to eq 'from env'
172
+ end
173
+
174
+ it 'may be set explicitly' do
175
+ subject.userinfo_endpoint = 'overridden'
176
+ expect(subject.userinfo_endpoint).to eq 'overridden'
177
+ end
178
+
179
+ context 'when not set' do
180
+ it 'defaults to endpoint from provider config' do
181
+ stub_env('OPENID_USERINFO_ENDPOINT')
182
+ ep = with_valid_issuer.userinfo_endpoint
183
+ expect(ep).to eq 'https://login.windows.net/common/openid/userinfo'
184
+ end
185
+ end
186
+ end
187
+
188
+ describe '#public_keys' do
189
+ it 'may be set explicitly' do
190
+ subject.public_keys = []
191
+ expect(subject.public_keys).to eq []
192
+ end
193
+
194
+ context 'when not set' do
195
+ it 'retrieves public keys from provider' do
196
+ keys = with_valid_issuer.public_keys
197
+ expect(keys.first).to be_an OpenSSL::PKey::PKey
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OpenIDTokenProxy::Error do
4
+ subject { described_class.new 'error message' }
5
+
6
+ describe '#to_json' do
7
+ it 'includes error message' do
8
+ expect(subject.to_json).to eq(error: 'error message')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OpenIDTokenProxy::Token::Authentication, type: :controller do
4
+ let(:authorization_uri) { 'https://id.hyper.no/authorize' }
5
+ let(:access_token) { 'access token' }
6
+ let(:token) { OpenIDTokenProxy::Token.new(access_token) }
7
+
8
+ before do
9
+ allow(token).to receive(:validate!).and_return true
10
+ allow(OpenIDTokenProxy::Token).to receive(:decode!).and_return token
11
+ end
12
+
13
+ controller(ApplicationController) do
14
+ include OpenIDTokenProxy::Token::Authentication
15
+
16
+ require_valid_token
17
+
18
+ def index
19
+ render text: 'Authentication successful', status: :ok
20
+ end
21
+ end
22
+
23
+ context 'when token proxy errors are encountered' do
24
+ it 'results in 401 UNAUTHORIZED with authentication URI' do
25
+ expect(token).to receive(:validate!).and_raise OpenIDTokenProxy::Error
26
+ OpenIDTokenProxy.configure_temporarily do |config|
27
+ config.authorization_uri = authorization_uri
28
+ get :index
29
+ end
30
+ expect(response).to have_http_status :unauthorized
31
+ expect(response.headers['X-Authentication-URL']).to eq authorization_uri
32
+ end
33
+ end
34
+
35
+ context 'when no token proxy errors are encountered' do
36
+ it 'executes actions normally' do
37
+ get :index
38
+ expect(response).to have_http_status :ok
39
+ expect(response.body).to eq 'Authentication successful'
40
+ end
41
+ end
42
+
43
+ describe '#current_token' do
44
+ it 'returns current valid token' do
45
+ expect(controller.current_token).to eq token
46
+ end
47
+ end
48
+
49
+ describe '#raw_token' do
50
+ it 'may be provided as parameter' do
51
+ get :index, token: 'raw token'
52
+ expect(controller.raw_token).to eq 'raw token'
53
+ end
54
+
55
+ it 'may be provided through authorization header' do
56
+ request.headers['Authorization'] = 'Bearer raw token'
57
+ get :index
58
+ expect(controller.raw_token).to eq 'raw token'
59
+ end
60
+
61
+ it 'may be provided through X-Token header' do
62
+ request.headers['X-Token'] = 'raw token'
63
+ get :index
64
+ expect(controller.raw_token).to eq 'raw token'
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OpenIDTokenProxy::Token::Refresh, type: :controller do
4
+ let(:authorization_uri) { 'https://id.hyper.no/authorize' }
5
+ let(:refresh_token) { 'refresh token' }
6
+ let(:token) {
7
+ OpenIDTokenProxy::Token.new('expired access token', nil, refresh_token)
8
+ }
9
+ let(:refreshed_token) {
10
+ OpenIDTokenProxy::Token.new('new access token', nil, 'new refresh token')
11
+ }
12
+
13
+ before do
14
+ expect(token).to receive(:validate!).and_raise OpenIDTokenProxy::Token::Expired
15
+ expect(OpenIDTokenProxy::Token).to receive(:decode!).and_return token
16
+ allow(OpenIDTokenProxy.client).to receive(:retrieve_token!).with(
17
+ refresh_token: refresh_token
18
+ ).and_return refreshed_token
19
+ end
20
+
21
+ controller(ApplicationController) do
22
+ include OpenIDTokenProxy::Token::Refresh
23
+
24
+ require_valid_token
25
+
26
+ def index
27
+ render text: 'Refresh successful', status: :ok
28
+ end
29
+ end
30
+
31
+ context 'when token has expired' do
32
+ context 'when refresh token could not be exchanged' do
33
+ it 'results in 401 UNAUTHORIZED with authentication URI' do
34
+ error = OpenIDTokenProxy::Client::RefreshTokenError.new 'msg'
35
+ expect(OpenIDTokenProxy.client).to receive(:retrieve_token!).with(
36
+ refresh_token: refresh_token
37
+ ).and_raise error
38
+ OpenIDTokenProxy.configure_temporarily do |config|
39
+ config.authorization_uri = authorization_uri
40
+ get :index, refresh_token: refresh_token
41
+ end
42
+ expect(response).to have_http_status :unauthorized
43
+ expect(response.headers['X-Authentication-URL']).to eq authorization_uri
44
+ expect(response.headers).not_to include 'X-Token', 'X-Refresh-Token'
45
+ end
46
+ end
47
+
48
+ context 'when token was refreshed successfully' do
49
+ it 'executes actions normally returning new tokens as headers' do
50
+ get :index, refresh_token: refresh_token
51
+ expect(response).to have_http_status :ok
52
+ expect(response.body).to eq 'Refresh successful'
53
+ expect(response.headers['X-Token']).to eq 'new access token'
54
+ expect(response.headers['X-Refresh-Token']).to eq 'new refresh token'
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#raw_refresh_token' do
60
+ it 'may be provided as parameter' do
61
+ get :index, refresh_token: refresh_token
62
+ expect(controller.raw_refresh_token).to eq 'refresh token'
63
+ end
64
+
65
+ it 'may be provided through X-Refresh-Token header' do
66
+ request.headers['X-Refresh-Token'] = refresh_token
67
+ get :index
68
+ expect(controller.raw_refresh_token).to eq 'refresh token'
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OpenIDTokenProxy::Token do
4
+ subject { described_class.new 'access token', id_token }
5
+
6
+ let(:audience) { 'audience' }
7
+ let(:client_id) { 'client ID' }
8
+ let(:issuer) { 'issuer' }
9
+ let(:expiry_date) { 2.hours.from_now }
10
+
11
+ let(:id_token) {
12
+ double(
13
+ exp: expiry_date,
14
+ aud: audience,
15
+ iss: issuer,
16
+ raw_attributes: {
17
+ 'appid' => client_id
18
+ }
19
+ )
20
+ }
21
+
22
+ describe '#to_s' do
23
+ it 'returns access token' do
24
+ expect(subject.to_s).to eq 'access token'
25
+ end
26
+ end
27
+
28
+ describe '#[]' do
29
+ it 'retrieves identity attributes' do
30
+ expect(subject['appid']).to eq client_id
31
+ end
32
+ end
33
+
34
+ describe '#validate!' do
35
+ context 'when token has expired' do
36
+ let(:expiry_date) { 2.hours.ago }
37
+
38
+ it 'raises' do
39
+ expect do
40
+ subject.validate!
41
+ end.to raise_error OpenIDTokenProxy::Token::Expired
42
+ end
43
+ end
44
+
45
+ context 'when application differs' do
46
+ it 'raises' do
47
+ expect do
48
+ subject.validate! client_id: 'expected client ID'
49
+ end.to raise_error OpenIDTokenProxy::Token::InvalidApplication
50
+ end
51
+ end
52
+
53
+ context 'when audience differs' do
54
+ it 'raises' do
55
+ expect do
56
+ subject.validate! audience: 'expected audience'
57
+ end.to raise_error OpenIDTokenProxy::Token::InvalidAudience
58
+ end
59
+ end
60
+
61
+ context 'when issuer differs' do
62
+ it 'raises' do
63
+ expect do
64
+ subject.validate! issuer: 'expected issuer'
65
+ end.to raise_error OpenIDTokenProxy::Token::InvalidIssuer
66
+ end
67
+ end
68
+
69
+ context 'when all is well' do
70
+ it 'returns true' do
71
+ assertions = {
72
+ audience: audience,
73
+ client_id: client_id,
74
+ issuer: issuer
75
+ }
76
+ expect(subject.validate! assertions).to be_truthy
77
+ end
78
+ end
79
+ end
80
+
81
+ describe '#expired?' do
82
+ context 'when token has expired' do
83
+ let(:expiry_date) { 2.hours.ago }
84
+ it { should be_expired }
85
+ end
86
+
87
+ context 'when token has not yet expired' do
88
+ it { should_not be_expired }
89
+ end
90
+ end
91
+
92
+ describe '::decode!' do
93
+ let(:keys) { [double] }
94
+
95
+ context 'when token is omitted' do
96
+ it 'raises' do
97
+ expect do
98
+ described_class.decode! '', keys
99
+ end.to raise_error OpenIDTokenProxy::Token::Required
100
+ end
101
+ end
102
+
103
+ context 'when token is malformed' do
104
+ it 'raises' do
105
+ expect do
106
+ described_class.decode! 'malformed token', keys
107
+ end.to raise_error OpenIDTokenProxy::Token::Malformed
108
+ end
109
+ end
110
+
111
+ context 'when token is well-formed' do
112
+ context 'with invalid signature or missing public keys' do
113
+ it 'raises' do
114
+ expect do
115
+ described_class.decode! 'well-formed token', []
116
+ end.to raise_error OpenIDTokenProxy::Token::UnverifiableSignature
117
+ end
118
+ end
119
+
120
+ context 'with valid signature' do
121
+ it 'returns token with an identity token' do
122
+ object = double(raw_attributes: {
123
+ iss: double,
124
+ sub: double,
125
+ aud: double,
126
+ exp: double,
127
+ iat: double
128
+ })
129
+ expect(OpenIDConnect::RequestObject).to receive(:decode).and_return object
130
+ token = described_class.decode! 'valid token', keys
131
+ expect(token).to be_an OpenIDTokenProxy::Token
132
+ expect(token.access_token).to eq 'valid token'
133
+ expect(token.id_token).to be_an OpenIDConnect::ResponseObject::IdToken
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OpenIDTokenProxy do
4
+ describe '::client' do
5
+ it 'returns global client' do
6
+ client = described_class.client
7
+ expect(client).to eq described_class.client
8
+ expect(client).to be_a OpenIDTokenProxy::Client
9
+ end
10
+ end
11
+
12
+ describe '::config' do
13
+ it 'returns global configuration' do
14
+ config = described_class.config
15
+ expect(config).to eq described_class.config
16
+ expect(config).to be_a OpenIDTokenProxy::Config
17
+ end
18
+ end
19
+
20
+ describe '::configure' do
21
+ it 'yields configuration' do
22
+ expect do |probe|
23
+ described_class.configure &probe
24
+ end.to yield_with_args OpenIDTokenProxy.config
25
+ end
26
+ end
27
+
28
+ describe '::configure_temporarily' do
29
+ it 'yields temporary configuration' do
30
+ original = OpenIDTokenProxy.config
31
+ described_class.configure_temporarily do |config|
32
+ expect(OpenIDTokenProxy.config).to eq config
33
+ expect(config).not_to eq original
34
+ end
35
+ expect(OpenIDTokenProxy.config).to eq original
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,88 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start do
9
+ add_filter '/spec/dummy/config/initializers'
10
+ end
11
+
12
+ ENV['RAILS_ENV'] = 'test'
13
+ require File.expand_path('../../spec/dummy/config/environment.rb', __FILE__)
14
+
15
+ require 'webmock/rspec'
16
+
17
+ require 'pry'
18
+ require 'rspec/rails'
19
+
20
+ # Load support files
21
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
22
+
23
+ require 'openid_token_proxy'
24
+
25
+ RSpec.configure do |config|
26
+ config.expect_with :rspec do |expectations|
27
+ # This option will default to `true` in RSpec 4. It makes the `description`
28
+ # and `failure_message` of custom matchers include text for helper methods
29
+ # defined using `chain`, e.g.:
30
+ # be_bigger_than(2).and_smaller_than(4).description
31
+ # # => "be bigger than 2 and smaller than 4"
32
+ # ...rather than:
33
+ # # => "be bigger than 2"
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ config.mock_with :rspec do |mocks|
38
+ # Prevents you from mocking or stubbing a method that does not exist on
39
+ # a real object. This is generally recommended, and will default to
40
+ # `true` in RSpec 4.
41
+ mocks.verify_partial_doubles = true
42
+ end
43
+
44
+ # These two settings work together to allow you to limit a spec run
45
+ # to individual examples or groups you care about by tagging them with
46
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
47
+ # get run.
48
+ config.filter_run :focus
49
+ config.run_all_when_everything_filtered = true
50
+
51
+ # Limits the available syntax to the non-monkey patched syntax that is
52
+ # recommended. For more details, see:
53
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
54
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
55
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
56
+ config.disable_monkey_patching!
57
+
58
+ # This setting enables warnings. It's recommended, but in some cases may
59
+ # be too noisy due to issues in dependencies.
60
+ # config.warnings = true
61
+
62
+ # Many RSpec users commonly either run the entire suite or an individual
63
+ # file, and it's useful to allow more verbose output when running an
64
+ # individual spec file.
65
+ # if config.files_to_run.one?
66
+ # # Use the documentation formatter for detailed output,
67
+ # # unless a formatter has already been configured
68
+ # # (e.g. via a command-line flag).
69
+ # config.default_formatter = 'doc'
70
+ # end
71
+
72
+ # Print the 10 slowest examples and example groups at the
73
+ # end of the spec run, to help surface which specs are running
74
+ # particularly slow.
75
+ # config.profile_examples = 10
76
+
77
+ # Run specs in random order to surface order dependencies. If you find an
78
+ # order dependency and want to debug it, you can fix the order by providing
79
+ # the seed, which is printed after each run.
80
+ # --seed 1234
81
+ config.order = :random
82
+
83
+ # Seed global randomization in this process using the `--seed` CLI option.
84
+ # Setting this allows you to use `--seed` to deterministically reproduce
85
+ # test failures related to randomization by passing the same `--seed` value
86
+ # as the one that triggered the failure.
87
+ Kernel.srand config.seed
88
+ end
@@ -0,0 +1,4 @@
1
+ def stub_env(name, value = nil)
2
+ allow(ENV).to receive(:[]).with(anything)
3
+ allow(ENV).to receive(:[]).with(name).and_return(value)
4
+ end
@@ -0,0 +1,3 @@
1
+ def fixture(file)
2
+ File.read "spec/fixtures/#{file}"
3
+ end