oauth2 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile DELETED
@@ -1,39 +0,0 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
4
- require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new(:spec)
6
-
7
- task :test => :spec
8
-
9
- namespace :doc do
10
- require 'rdoc/task'
11
- require File.expand_path('../lib/oauth2/version', __FILE__)
12
- RDoc::Task.new do |rdoc|
13
- rdoc.rdoc_dir = 'rdoc'
14
- rdoc.title = "oauth2 #{OAuth2::Version}"
15
- rdoc.main = 'README.md'
16
- rdoc.rdoc_files.include('README.md', 'LICENSE.md', 'lib/**/*.rb')
17
- end
18
- end
19
-
20
- begin
21
- require 'rubocop/rake_task'
22
- RuboCop::RakeTask.new
23
- rescue LoadError
24
- task :rubocop do
25
- $stderr.puts 'RuboCop is disabled'
26
- end
27
- end
28
-
29
- require 'yardstick/rake/measurement'
30
- Yardstick::Rake::Measurement.new do |measurement|
31
- measurement.output = 'measurement/report.txt'
32
- end
33
-
34
- require 'yardstick/rake/verify'
35
- Yardstick::Rake::Verify.new do |verify|
36
- verify.threshold = 58.8
37
- end
38
-
39
- task :default => [:spec, :rubocop, :verify_measurements]
@@ -1,42 +0,0 @@
1
- require 'simplecov'
2
- require 'coveralls'
3
-
4
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
- SimpleCov::Formatter::HTMLFormatter,
6
- Coveralls::SimpleCov::Formatter
7
- ]
8
-
9
- SimpleCov.start do
10
- add_filter '/spec/'
11
- minimum_coverage(95.33)
12
- end
13
-
14
- require 'oauth2'
15
- require 'addressable/uri'
16
- require 'rspec'
17
-
18
- RSpec.configure do |config|
19
- config.expect_with :rspec do |c|
20
- c.syntax = :expect
21
- end
22
- end
23
-
24
- Faraday.default_adapter = :test
25
-
26
- RSpec.configure do |conf|
27
- include OAuth2
28
- end
29
-
30
- def capture_output(&block)
31
- begin
32
- old_stdout = $stdout
33
- $stdout = StringIO.new
34
- block.call
35
- result = $stdout.string
36
- ensure
37
- $stdout = old_stdout
38
- end
39
- result
40
- end
41
-
42
- VERBS = [:get, :post, :put, :delete]
@@ -1,169 +0,0 @@
1
- require 'helper'
2
-
3
- describe AccessToken do
4
- let(:token) { 'monkey' }
5
- let(:refresh_body) { MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => 'refresh_bar') }
6
- let(:client) do
7
- Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
8
- builder.request :url_encoded
9
- builder.adapter :test do |stub|
10
- VERBS.each do |verb|
11
- stub.send(verb, '/token/header') { |env| [200, {}, env[:request_headers]['Authorization']] }
12
- stub.send(verb, "/token/query?access_token=#{token}") { |env| [200, {}, Addressable::URI.parse(env[:url]).query_values['access_token']] }
13
- stub.send(verb, '/token/body') { |env| [200, {}, env[:body]] }
14
- end
15
- stub.post('/oauth/token') { |env| [200, {'Content-Type' => 'application/json'}, refresh_body] }
16
- end
17
- end
18
- end
19
-
20
- subject { AccessToken.new(client, token) }
21
-
22
- describe '#initialize' do
23
- it 'assigns client and token' do
24
- expect(subject.client).to eq(client)
25
- expect(subject.token).to eq(token)
26
- end
27
-
28
- it 'assigns extra params' do
29
- target = AccessToken.new(client, token, 'foo' => 'bar')
30
- expect(target.params).to include('foo')
31
- expect(target.params['foo']).to eq('bar')
32
- end
33
-
34
- def assert_initialized_token(target)
35
- expect(target.token).to eq(token)
36
- expect(target).to be_expires
37
- expect(target.params.keys).to include('foo')
38
- expect(target.params['foo']).to eq('bar')
39
- end
40
-
41
- it 'initializes with a Hash' do
42
- hash = {:access_token => token, :expires_at => Time.now.to_i + 200, 'foo' => 'bar'}
43
- target = AccessToken.from_hash(client, hash)
44
- assert_initialized_token(target)
45
- end
46
-
47
- it 'initalizes with a form-urlencoded key/value string' do
48
- kvform = "access_token=#{token}&expires_at=#{Time.now.to_i + 200}&foo=bar"
49
- target = AccessToken.from_kvform(client, kvform)
50
- assert_initialized_token(target)
51
- end
52
-
53
- it 'sets options' do
54
- target = AccessToken.new(client, token, :param_name => 'foo', :header_format => 'Bearer %', :mode => :body)
55
- expect(target.options[:param_name]).to eq('foo')
56
- expect(target.options[:header_format]).to eq('Bearer %')
57
- expect(target.options[:mode]).to eq(:body)
58
- end
59
-
60
- it 'initializes with a string expires_at' do
61
- hash = {:access_token => token, :expires_at => '1361396829', 'foo' => 'bar'}
62
- target = AccessToken.from_hash(client, hash)
63
- assert_initialized_token(target)
64
- expect(target.expires_at).to be_a(Integer)
65
- end
66
- end
67
-
68
- describe '#request' do
69
- context ':mode => :header' do
70
- before do
71
- subject.options[:mode] = :header
72
- end
73
-
74
- VERBS.each do |verb|
75
- it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do
76
- expect(subject.post('/token/header').body).to include(token)
77
- end
78
- end
79
- end
80
-
81
- context ':mode => :query' do
82
- before do
83
- subject.options[:mode] = :query
84
- end
85
-
86
- VERBS.each do |verb|
87
- it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do
88
- expect(subject.post('/token/query').body).to eq(token)
89
- end
90
- end
91
- end
92
-
93
- context ':mode => :body' do
94
- before do
95
- subject.options[:mode] = :body
96
- end
97
-
98
- VERBS.each do |verb|
99
- it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do
100
- expect(subject.post('/token/body').body.split('=').last).to eq(token)
101
- end
102
- end
103
- end
104
- end
105
-
106
- describe '#expires?' do
107
- it 'is false if there is no expires_at' do
108
- expect(AccessToken.new(client, token)).not_to be_expires
109
- end
110
-
111
- it 'is true if there is an expires_in' do
112
- expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600)).to be_expires
113
- end
114
-
115
- it 'is true if there is an expires_at' do
116
- expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => Time.now.getutc.to_i + 600)).to be_expires
117
- end
118
- end
119
-
120
- describe '#expired?' do
121
- it 'is false if there is no expires_in or expires_at' do
122
- expect(AccessToken.new(client, token)).not_to be_expired
123
- end
124
-
125
- it 'is false if expires_in is in the future' do
126
- expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 10_800)).not_to be_expired
127
- end
128
-
129
- it 'is true if expires_at is in the past' do
130
- access = AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600)
131
- @now = Time.now + 10_800
132
- allow(Time).to receive(:now).and_return(@now)
133
- expect(access).to be_expired
134
- end
135
-
136
- end
137
-
138
- describe '#refresh!' do
139
- let(:access) do
140
- AccessToken.new(client, token, :refresh_token => 'abaca',
141
- :expires_in => 600,
142
- :param_name => 'o_param')
143
- end
144
-
145
- it 'returns a refresh token with appropriate values carried over' do
146
- refreshed = access.refresh!
147
- expect(access.client).to eq(refreshed.client)
148
- expect(access.options[:param_name]).to eq(refreshed.options[:param_name])
149
- end
150
-
151
- context 'with a nil refresh_token in the response' do
152
- let(:refresh_body) { MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => nil) }
153
-
154
- it 'copies the refresh_token from the original token' do
155
- refreshed = access.refresh!
156
-
157
- expect(refreshed.refresh_token).to eq(access.refresh_token)
158
- end
159
- end
160
- end
161
-
162
- describe '#to_hash' do
163
- it 'return a hash equals to the hash used to initialize access token' do
164
- hash = {:access_token => token, :refresh_token => 'foobar', :expires_at => Time.now.to_i + 200, 'foo' => 'bar'}
165
- access_token = AccessToken.from_hash(client, hash.clone)
166
- expect(access_token.to_hash).to eq(hash)
167
- end
168
- end
169
- end
@@ -1,215 +0,0 @@
1
- require 'helper'
2
-
3
- describe OAuth2::Client do
4
- let!(:error_value) { 'invalid_token' }
5
- let!(:error_description_value) { 'bad bad token' }
6
-
7
- subject do
8
- OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
9
- builder.adapter :test do |stub|
10
- stub.get('/success') { |env| [200, {'Content-Type' => 'text/awesome'}, 'yay'] }
11
- stub.get('/reflect') { |env| [200, {}, env[:body]] }
12
- stub.post('/reflect') { |env| [200, {}, env[:body]] }
13
- stub.get('/unauthorized') { |env| [401, {'Content-Type' => 'application/json'}, MultiJson.encode(:error => error_value, :error_description => error_description_value)] }
14
- stub.get('/conflict') { |env| [409, {'Content-Type' => 'text/plain'}, 'not authorized'] }
15
- stub.get('/redirect') { |env| [302, {'Content-Type' => 'text/plain', 'location' => '/success'}, ''] }
16
- stub.post('/redirect') { |env| [303, {'Content-Type' => 'text/plain', 'location' => '/reflect'}, ''] }
17
- stub.get('/error') { |env| [500, {'Content-Type' => 'text/plain'}, 'unknown error'] }
18
- stub.get('/empty_get') { |env| [204, {}, nil] }
19
- end
20
- end
21
- end
22
-
23
- describe '#initialize' do
24
- it 'assigns id and secret' do
25
- expect(subject.id).to eq('abc')
26
- expect(subject.secret).to eq('def')
27
- end
28
-
29
- it 'assigns site from the options hash' do
30
- expect(subject.site).to eq('https://api.example.com')
31
- end
32
-
33
- it 'assigns Faraday::Connection#host' do
34
- expect(subject.connection.host).to eq('api.example.com')
35
- end
36
-
37
- it 'leaves Faraday::Connection#ssl unset' do
38
- expect(subject.connection.ssl).to be_empty
39
- end
40
-
41
- it 'is able to pass a block to configure the connection' do
42
- connection = double('connection')
43
- builder = double('builder')
44
- allow(connection).to receive(:build).and_yield(builder)
45
- allow(Faraday::Connection).to receive(:new).and_return(connection)
46
-
47
- expect(builder).to receive(:adapter).with(:test)
48
-
49
- OAuth2::Client.new('abc', 'def') do |client|
50
- client.adapter :test
51
- end.connection
52
- end
53
-
54
- it 'defaults raise_errors to true' do
55
- expect(subject.options[:raise_errors]).to be true
56
- end
57
-
58
- it 'allows true/false for raise_errors option' do
59
- client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => false)
60
- expect(client.options[:raise_errors]).to be false
61
- client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true)
62
- expect(client.options[:raise_errors]).to be true
63
- end
64
-
65
- it 'allows override of raise_errors option' do
66
- client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true) do |builder|
67
- builder.adapter :test do |stub|
68
- stub.get('/notfound') { |env| [404, {}, nil] }
69
- end
70
- end
71
- expect(client.options[:raise_errors]).to be true
72
- expect { client.request(:get, '/notfound') }.to raise_error(OAuth2::Error)
73
- response = client.request(:get, '/notfound', :raise_errors => false)
74
- expect(response.status).to eq(404)
75
- end
76
-
77
- it 'allows get/post for access_token_method option' do
78
- client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :get)
79
- expect(client.options[:access_token_method]).to eq(:get)
80
- client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :post)
81
- expect(client.options[:access_token_method]).to eq(:post)
82
- end
83
-
84
- it 'does not mutate the opts hash argument' do
85
- opts = {:site => 'http://example.com/'}
86
- opts2 = opts.dup
87
- OAuth2::Client.new 'abc', 'def', opts
88
- expect(opts).to eq(opts2)
89
- end
90
- end
91
-
92
- %w(authorize token).each do |url_type|
93
- describe ":#{url_type}_url option" do
94
- it "defaults to a path of /oauth/#{url_type}" do
95
- expect(subject.send("#{url_type}_url")).to eq("https://api.example.com/oauth/#{url_type}")
96
- end
97
-
98
- it "is settable via the :#{url_type}_url option" do
99
- subject.options[:"#{url_type}_url"] = '/oauth/custom'
100
- expect(subject.send("#{url_type}_url")).to eq('https://api.example.com/oauth/custom')
101
- end
102
-
103
- it 'allows a different host than the site' do
104
- subject.options[:"#{url_type}_url"] = 'https://api.foo.com/oauth/custom'
105
- expect(subject.send("#{url_type}_url")).to eq('https://api.foo.com/oauth/custom')
106
- end
107
- end
108
- end
109
-
110
- describe '#request' do
111
- it 'works with a null response body' do
112
- expect(subject.request(:get, 'empty_get').body).to eq('')
113
- end
114
-
115
- it 'returns on a successful response' do
116
- response = subject.request(:get, '/success')
117
- expect(response.body).to eq('yay')
118
- expect(response.status).to eq(200)
119
- expect(response.headers).to eq('Content-Type' => 'text/awesome')
120
- end
121
-
122
- it 'outputs to $stdout when OAUTH_DEBUG=true' do
123
- allow(ENV).to receive(:[]).with('http_proxy').and_return(nil)
124
- allow(ENV).to receive(:[]).with('OAUTH_DEBUG').and_return('true')
125
- output = capture_output do
126
- subject.request(:get, '/success')
127
- end
128
-
129
- expect(output).to include 'INFO -- : get https://api.example.com/success', 'INFO -- : get https://api.example.com/success'
130
- end
131
-
132
- it 'posts a body' do
133
- response = subject.request(:post, '/reflect', :body => 'foo=bar')
134
- expect(response.body).to eq('foo=bar')
135
- end
136
-
137
- it 'follows redirects properly' do
138
- response = subject.request(:get, '/redirect')
139
- expect(response.body).to eq('yay')
140
- expect(response.status).to eq(200)
141
- expect(response.headers).to eq('Content-Type' => 'text/awesome')
142
- end
143
-
144
- it 'redirects using GET on a 303' do
145
- response = subject.request(:post, '/redirect', :body => 'foo=bar')
146
- expect(response.body).to be_empty
147
- expect(response.status).to eq(200)
148
- end
149
-
150
- it 'obeys the :max_redirects option' do
151
- max_redirects = subject.options[:max_redirects]
152
- subject.options[:max_redirects] = 0
153
- response = subject.request(:get, '/redirect')
154
- expect(response.status).to eq(302)
155
- subject.options[:max_redirects] = max_redirects
156
- end
157
-
158
- it 'returns if raise_errors is false' do
159
- subject.options[:raise_errors] = false
160
- response = subject.request(:get, '/unauthorized')
161
-
162
- expect(response.status).to eq(401)
163
- expect(response.headers).to eq('Content-Type' => 'application/json')
164
- expect(response.error).not_to be_nil
165
- end
166
-
167
- %w(/unauthorized /conflict /error).each do |error_path|
168
- it "raises OAuth2::Error on error response to path #{error_path}" do
169
- expect { subject.request(:get, error_path) }.to raise_error(OAuth2::Error)
170
- end
171
- end
172
-
173
- it 'parses OAuth2 standard error response' do
174
- begin
175
- subject.request(:get, '/unauthorized')
176
- rescue StandardError => e
177
- expect(e.code).to eq(error_value)
178
- expect(e.description).to eq(error_description_value)
179
- expect(e.to_s).to match(/#{error_value}/)
180
- expect(e.to_s).to match(/#{error_description_value}/)
181
- end
182
- end
183
-
184
- it 'provides the response in the Exception' do
185
- begin
186
- subject.request(:get, '/error')
187
- rescue StandardError => e
188
- expect(e.response).not_to be_nil
189
- expect(e.to_s).to match(/unknown error/)
190
- end
191
- end
192
- end
193
-
194
- it 'instantiates an AuthCode strategy with this client' do
195
- expect(subject.auth_code).to be_kind_of(OAuth2::Strategy::AuthCode)
196
- end
197
-
198
- it 'instantiates an Implicit strategy with this client' do
199
- expect(subject.implicit).to be_kind_of(OAuth2::Strategy::Implicit)
200
- end
201
-
202
- context 'with SSL options' do
203
- subject do
204
- cli = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :ssl => {:ca_file => 'foo.pem'})
205
- cli.connection.build do |b|
206
- b.adapter :test
207
- end
208
- cli
209
- end
210
-
211
- it 'passes the SSL options along to Faraday::Connection#ssl' do
212
- expect(subject.connection.ssl.fetch(:ca_file)).to eq('foo.pem')
213
- end
214
- end
215
- end