oauth2-client 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.
- checksums.yaml +15 -0
- data/.gitignore +10 -0
- data/.travis.yml +1 -0
- data/Gemfile +7 -12
- data/Gemfile.lock +17 -9
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +109 -19
- data/examples/github_client.rb +42 -0
- data/examples/google_client.rb +17 -15
- data/examples/yammer_client.rb +96 -0
- data/lib/oauth2/client.rb +12 -0
- data/lib/oauth2/connection.rb +8 -12
- data/lib/oauth2/grant/authorization_code.rb +7 -8
- data/lib/oauth2/version.rb +1 -1
- data/oauth2-client.gemspec +23 -13
- data/spec/examples/github_client_spec.rb +59 -0
- data/spec/examples/google_client_spec.rb +54 -78
- data/spec/examples/yammer_client_spec.rb +75 -0
- data/spec/oauth2/client_spec.rb +4 -4
- data/spec/oauth2/connection_spec.rb +56 -43
- data/spec/oauth2/grant/authorization_code_spec.rb +7 -2
- data/spec/oauth2/grant/client_credentials_spec.rb +4 -1
- data/spec/oauth2/grant/device_spec.rb +7 -2
- data/spec/oauth2/grant/implicit_spec.rb +4 -1
- data/spec/oauth2/grant/password_spec.rb +4 -1
- data/spec/oauth2/grant/refresh_token_spec.rb +4 -1
- data/spec/spec_helper.rb +18 -1
- metadata +73 -18
- data/TODO +0 -10
- data/spec/.DS_Store +0 -0
- data/spec/mocks/oauth_client.yml +0 -60
data/lib/oauth2/client.rb
CHANGED
@@ -32,6 +32,18 @@ module OAuth2
|
|
32
32
|
@connection_options = options
|
33
33
|
end
|
34
34
|
|
35
|
+
# Token scope definitions vary by service e.g Google uses space delimited scopes,
|
36
|
+
# while Github uses comma seperated scopes. This method allows us to normalize
|
37
|
+
# the token scopes
|
38
|
+
#
|
39
|
+
# @see http://developer.github.com/v3/oauth/#scopes, https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl
|
40
|
+
def normalize_scope(scope, sep=' ')
|
41
|
+
unless (scope.is_a?(String) || scope.is_a?(Array))
|
42
|
+
raise ArgumentError.new("Expected scope of type String or Array but was: #{scope.class.name}")
|
43
|
+
end
|
44
|
+
(scope.is_a?(Array) && scope.join(sep)) || scope
|
45
|
+
end
|
46
|
+
|
35
47
|
def implicit
|
36
48
|
OAuth2::Grant::Implicit.new(self)
|
37
49
|
end
|
data/lib/oauth2/connection.rb
CHANGED
@@ -100,25 +100,21 @@ module OAuth2
|
|
100
100
|
headers = @headers.merge(opts.fetch(:headers, {}))
|
101
101
|
params = opts[:params] || {}
|
102
102
|
query = Addressable::URI.form_encode(params)
|
103
|
-
method = method.
|
103
|
+
method = method.to_sym
|
104
104
|
normalized_path = query.empty? ? path : [path, query].join("?")
|
105
105
|
client = http_connection(opts.fetch(:connection_options, {}))
|
106
106
|
|
107
|
-
if (method ==
|
107
|
+
if (method == :post || method == :put)
|
108
108
|
headers['Content-Type'] ||= 'application/x-www-form-urlencoded'
|
109
109
|
end
|
110
110
|
|
111
111
|
case method
|
112
|
-
when
|
113
|
-
response = client.
|
114
|
-
when
|
115
|
-
response = client.
|
116
|
-
when 'put'
|
117
|
-
response = client.put(path, query, headers)
|
118
|
-
when 'delete'
|
119
|
-
response = client.delete(normalized_path, headers)
|
112
|
+
when :get, :delete
|
113
|
+
response = client.send(method, normalized_path, headers)
|
114
|
+
when :post, :put
|
115
|
+
response = client.send(method, path, query, headers)
|
120
116
|
else
|
121
|
-
raise UnhandledHTTPMethodError.new("Unsupported HTTP method, #{method
|
117
|
+
raise UnhandledHTTPMethodError.new("Unsupported HTTP method, #{method}")
|
122
118
|
end
|
123
119
|
|
124
120
|
status = response.code.to_i
|
@@ -129,7 +125,7 @@ module OAuth2
|
|
129
125
|
if status == 303
|
130
126
|
method = :get
|
131
127
|
params = nil
|
132
|
-
headers.delete('Content-Type')
|
128
|
+
headers.delete('Content-Type')
|
133
129
|
end
|
134
130
|
redirect_uri = Addressable::URI.parse(response.header['Location'])
|
135
131
|
conn = {
|
@@ -37,9 +37,7 @@ module OAuth2
|
|
37
37
|
#
|
38
38
|
# @param [Hash] opts options
|
39
39
|
def fetch_authorization_url(opts={})
|
40
|
-
opts[:
|
41
|
-
opts[:params] ||= {}
|
42
|
-
opts[:params].merge!(authorization_params)
|
40
|
+
opts[:params] = opts.fetch(:params, {}).merge(authorization_params)
|
43
41
|
method = opts.delete(:method) || :get
|
44
42
|
make_request(method, @authorize_path, opts)
|
45
43
|
end
|
@@ -50,15 +48,16 @@ module OAuth2
|
|
50
48
|
# @param [Hash] params additional params
|
51
49
|
# @param [Hash] opts options
|
52
50
|
def get_token(code, opts={})
|
53
|
-
opts[:params]
|
54
|
-
|
51
|
+
opts[:params] = {
|
52
|
+
:grant_type => grant_type,
|
53
|
+
:code => code
|
54
|
+
}.merge(opts.fetch(:params, {}))
|
55
|
+
|
55
56
|
opts[:authenticate] ||= :headers
|
56
57
|
method = opts.delete(:method) || :post
|
57
58
|
make_request(method, token_path, opts)
|
58
59
|
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
60
|
+
|
62
61
|
# Default authorization request parameters
|
63
62
|
def authorization_params
|
64
63
|
{
|
data/lib/oauth2/version.rb
CHANGED
data/oauth2-client.gemspec
CHANGED
@@ -1,13 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'oauth2/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.add_dependency 'json'
|
7
|
+
spec.add_dependency 'bcrypt-ruby', '~> 3.0.0'
|
8
|
+
spec.add_dependency 'addressable'
|
9
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
10
|
+
|
11
|
+
spec.name = 'oauth2-client'
|
12
|
+
spec.version = OAuth2::Version
|
13
|
+
spec.date = %q{2013-03-03}
|
14
|
+
spec.summary = "OAuth2 client wrapper in Ruby"
|
15
|
+
spec.description = "Create quick and dirty OAuth2 clients"
|
16
|
+
spec.authors = ["Kevin Mutyaba"]
|
17
|
+
spec.email = %q{tiabasnk@gmail.com}
|
18
|
+
spec.homepage = 'http://tiabas.github.com/oauth2-client/'
|
19
|
+
spec.files = `git ls-files`.split("\n")
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
spec.licenses = ['MIT']
|
22
|
+
spec.required_rubygems_version = '>= 1.3.6'
|
23
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'github_client'
|
3
|
+
|
4
|
+
describe GithubClient do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
GithubClient.new('https://github.com', '2945e6425da3d5d17ffc', '0a8f686f2835a70a79dbcece2ec63bc5079f40a8')
|
8
|
+
|
9
|
+
# GithubClient.new('https://github.com', '82f971d013e8d637a7e1', '1a1d59e1f8b8afa5f73e9dc9f17e25f7876e64ac')
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#webserver_authorization_url" do
|
13
|
+
it "returns the authorization url" do
|
14
|
+
auth_url = subject.webserver_authorization_url(
|
15
|
+
:scope => 'repo, user',
|
16
|
+
:state => '1kd84ur7q0c9rbtnd',
|
17
|
+
:redirect_uri => 'https://localhost/callback'
|
18
|
+
)
|
19
|
+
|
20
|
+
parsed_url = Addressable::URI.parse(auth_url)
|
21
|
+
expect(parsed_url.path).to eq '/login/oauth/authorize'
|
22
|
+
expect(parsed_url.query_values).to eq({
|
23
|
+
"client_id" => '2945e6425da3d5d17ffc',
|
24
|
+
"redirect_uri" => 'https://localhost/callback',
|
25
|
+
"response_type" => 'code',
|
26
|
+
"scope" => 'repo, user',
|
27
|
+
"state" => '1kd84ur7q0c9rbtnd'
|
28
|
+
})
|
29
|
+
expect(parsed_url.scheme).to eq 'https'
|
30
|
+
expect(parsed_url.host).to eq 'github.com'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#exchange_auth_code_for_token" do
|
35
|
+
it "makes a request to google oauth2 server" do
|
36
|
+
|
37
|
+
stub_request(:post, "https://github.com/login/oauth/access_token").with(
|
38
|
+
:body => {
|
39
|
+
:grant_type => 'authorization_code',
|
40
|
+
:code => 'IZuJJVnL49Cc',
|
41
|
+
:redirect_uri => 'https://localhost/callback',
|
42
|
+
:client_id => '2945e6425da3d5d17ffc',
|
43
|
+
:client_secret => '0a8f686f2835a70a79dbcece2ec63bc5079f40a8'
|
44
|
+
},
|
45
|
+
:headers => {
|
46
|
+
'Accept' => "application/json",
|
47
|
+
'User-Agent' => "OAuth2 Ruby Gem #{OAuth2::Version}",
|
48
|
+
'Content-Type' => "application/x-www-form-urlencoded"
|
49
|
+
}
|
50
|
+
)
|
51
|
+
response = subject.exchange_auth_code_for_token(
|
52
|
+
:params => {
|
53
|
+
:code => 'IZuJJVnL49Cc',
|
54
|
+
:redirect_uri => 'https://localhost/callback'
|
55
|
+
}
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -4,18 +4,7 @@ require 'google_client'
|
|
4
4
|
describe GoogleClient do
|
5
5
|
|
6
6
|
subject do
|
7
|
-
|
8
|
-
GoogleClient.new('https://accounts.google.com', '827502413694.apps.googleusercontent.com', 'a2nQpcUm2Dgq1chWdAvbXGTk',{
|
9
|
-
:token_path => '/o/oauth2/token',
|
10
|
-
:authorize_path => '/o/oauth2/auth',
|
11
|
-
:device_path => '/o/oauth2/device/code',
|
12
|
-
:connection_options => {
|
13
|
-
:headers => {
|
14
|
-
"User-Agent" => "GoOAuth2 0.1",
|
15
|
-
"Accept" => "application/json"
|
16
|
-
}
|
17
|
-
}
|
18
|
-
})
|
7
|
+
GoogleClient.new('https://accounts.google.com', '827502413694.apps.googleusercontent.com', 'a2nQpcUm2Dgq1chWdAvbXGTk')
|
19
8
|
end
|
20
9
|
#
|
21
10
|
# https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl
|
@@ -25,7 +14,7 @@ describe GoogleClient do
|
|
25
14
|
params = {
|
26
15
|
"approval_prompt" => "force",
|
27
16
|
"client_id" => "827502413694.apps.googleusercontent.com",
|
28
|
-
"redirect_uri" => "
|
17
|
+
"redirect_uri" => "https://localhost",
|
29
18
|
"response_type" =>"code",
|
30
19
|
"scope" => "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
|
31
20
|
"state" => "/profile",
|
@@ -35,7 +24,7 @@ describe GoogleClient do
|
|
35
24
|
auth_url = subject.webserver_authorization_url(
|
36
25
|
:scope => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
|
37
26
|
:state => '/profile',
|
38
|
-
:redirect_uri => '
|
27
|
+
:redirect_uri => 'https://localhost',
|
39
28
|
:approval_prompt => 'force',
|
40
29
|
:access_type => 'offline'
|
41
30
|
)
|
@@ -53,7 +42,7 @@ describe GoogleClient do
|
|
53
42
|
params = {
|
54
43
|
"approval_prompt"=>"force",
|
55
44
|
"client_id"=>"827502413694.apps.googleusercontent.com",
|
56
|
-
"redirect_uri"=>"
|
45
|
+
"redirect_uri"=>"https://localhost",
|
57
46
|
"response_type"=>"code",
|
58
47
|
"scope"=>"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
|
59
48
|
"state"=>"/profile"
|
@@ -65,7 +54,7 @@ describe GoogleClient do
|
|
65
54
|
'https://www.googleapis.com/auth/userinfo.profile'
|
66
55
|
],
|
67
56
|
:state => '/profile',
|
68
|
-
:redirect_uri => '
|
57
|
+
:redirect_uri => 'https://localhost',
|
69
58
|
:approval_prompt => 'force'
|
70
59
|
)
|
71
60
|
|
@@ -91,25 +80,23 @@ describe GoogleClient do
|
|
91
80
|
describe "#exchange_auth_code_for_token" do
|
92
81
|
it "makes a request to google oauth2 server" do
|
93
82
|
|
94
|
-
|
95
|
-
:
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
{
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
"Content-Type"=>"application/x-www-form-urlencoded"
|
83
|
+
stub_request(:post, "https://accounts.google.com/o/oauth2/token").with(
|
84
|
+
:body => {
|
85
|
+
:grant_type => 'authorization_code',
|
86
|
+
:code => '4/o3xJkRT6SM_TpohrxC7T-4o3kqu6.MmOGL795LbIZuJJVnL49Cc-uiE7LeAI',
|
87
|
+
:redirect_uri => 'https://localhost',
|
88
|
+
:client_id => '827502413694.apps.googleusercontent.com',
|
89
|
+
:client_secret => 'a2nQpcUm2Dgq1chWdAvbXGTk'
|
90
|
+
},
|
91
|
+
:headers => {
|
92
|
+
'Accept' => "application/json",
|
93
|
+
'User-Agent' => "OAuth2 Ruby Gem #{OAuth2::Version}",
|
94
|
+
'Content-Type' => "application/x-www-form-urlencoded"
|
107
95
|
}
|
108
|
-
)
|
109
|
-
|
110
|
-
subject.exchange_auth_code_for_token(
|
96
|
+
)
|
97
|
+
response = subject.exchange_auth_code_for_token(
|
111
98
|
:params => {
|
112
|
-
:code => '4/
|
99
|
+
:code => '4/o3xJkRT6SM_TpohrxC7T-4o3kqu6.MmOGL795LbIZuJJVnL49Cc-uiE7LeAI',
|
113
100
|
:redirect_uri => 'https://localhost'
|
114
101
|
}
|
115
102
|
)
|
@@ -144,26 +131,23 @@ describe GoogleClient do
|
|
144
131
|
|
145
132
|
describe "#refresh_token" do
|
146
133
|
it "makes a request to google to obtain new token" do
|
147
|
-
fake_response = double(
|
148
|
-
:code => '200',
|
149
|
-
:body => ''
|
150
|
-
)
|
151
134
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
135
|
+
stub_request(:post, "https://accounts.google.com/o/oauth2/token").with(
|
136
|
+
:body => {
|
137
|
+
:grant_type => 'refresh_token',
|
138
|
+
:refresh_token => '1/6BMfW9j53gdGImsiyUH5kU5RsR4zwI9lUVX-tqf8JXQ',
|
139
|
+
:client_id => '827502413694.apps.googleusercontent.com',
|
140
|
+
:client_secret => 'a2nQpcUm2Dgq1chWdAvbXGTk'
|
141
|
+
},
|
142
|
+
:headers => {
|
143
|
+
'Accept' => 'application/json',
|
144
|
+
'User-Agent' => 'OAuth2 Ruby Gem 1.1.0',
|
145
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
160
146
|
}
|
161
|
-
)
|
162
|
-
|
147
|
+
)
|
163
148
|
subject.refresh_access_token(
|
164
149
|
:params => {
|
165
|
-
:
|
166
|
-
:refresh_token => '2YotnFZFEjr1zCsicMWpAA'
|
150
|
+
:refresh_token => '1/6BMfW9j53gdGImsiyUH5kU5RsR4zwI9lUVX-tqf8JXQ'
|
167
151
|
}
|
168
152
|
)
|
169
153
|
end
|
@@ -171,21 +155,17 @@ describe GoogleClient do
|
|
171
155
|
|
172
156
|
describe "#get_device_code" do
|
173
157
|
it "makes a request to google to obtain a device code" do
|
174
|
-
|
175
|
-
:
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
"Accept"=>"application/json",
|
184
|
-
"User-Agent"=>"GoOAuth2 0.1",
|
185
|
-
"Content-Type"=>"application/x-www-form-urlencoded"
|
158
|
+
stub_request(:post, "https://accounts.google.com/o/oauth2/device/code").with(
|
159
|
+
:body => {
|
160
|
+
:scope => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
|
161
|
+
:client_id => '827502413694.apps.googleusercontent.com'
|
162
|
+
},
|
163
|
+
:headers => {
|
164
|
+
'Accept' => 'application/json',
|
165
|
+
'User-Agent' => 'OAuth2 Ruby Gem 1.1.0',
|
166
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
186
167
|
}
|
187
|
-
)
|
188
|
-
|
168
|
+
)
|
189
169
|
subject.get_device_code(
|
190
170
|
:params => {
|
191
171
|
:scope => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
|
@@ -196,22 +176,18 @@ describe GoogleClient do
|
|
196
176
|
|
197
177
|
describe "#exchange_device_code_for_token" do
|
198
178
|
it "makes request to google to obtain an access token" do
|
199
|
-
|
200
|
-
:
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
"User-Agent" => "GoOAuth2 0.1",
|
210
|
-
"Authorization"=>"Basic ODI3NTAyNDEzNjk0LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tOmEyblFwY1VtMkRncTFjaFdkQXZiWEdUaw==",
|
211
|
-
"Content-Type"=>"application/x-www-form-urlencoded"
|
179
|
+
stub_request(:post, "https://827502413694.apps.googleusercontent.com:a2nQpcUm2Dgq1chWdAvbXGTk@accounts.google.com/o/oauth2/token").with(
|
180
|
+
:body => {
|
181
|
+
:grant_type => 'http://oauth.net/grant_type/device/1.0',
|
182
|
+
:state => '/profile',
|
183
|
+
:code => 'G3Y6jU3a'
|
184
|
+
},
|
185
|
+
:headers => {
|
186
|
+
'Accept' => 'application/json',
|
187
|
+
'User-Agent' => 'OAuth2 Ruby Gem 1.1.0',
|
188
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
212
189
|
}
|
213
|
-
)
|
214
|
-
|
190
|
+
)
|
215
191
|
subject.exchange_device_code_for_token(
|
216
192
|
:params => {
|
217
193
|
:state => '/profile',
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'yammer_client'
|
3
|
+
|
4
|
+
describe YammerClient do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
YammerClient.new('https://www.yammer.com', 'PRbTcg9qjgKsp4jjpm1pw', 'a2nQpcUm2Dgq1chWdAvbXGTk')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#clientside_authorization_url" do
|
11
|
+
it "returns url string for obtaining authorization" do
|
12
|
+
params = {
|
13
|
+
'client_id' => 'PRbTcg9qjgKsp4jjpm1pw',
|
14
|
+
'response_type' => 'token'
|
15
|
+
}
|
16
|
+
|
17
|
+
auth_url = subject.clientside_authorization_url
|
18
|
+
|
19
|
+
parsed_url = Addressable::URI.parse(auth_url)
|
20
|
+
expect(parsed_url.path).to eq '/dialog/oauth/authorize'
|
21
|
+
expect(parsed_url.query_values).to eq params
|
22
|
+
expect(parsed_url.scheme).to eq 'https'
|
23
|
+
expect(parsed_url.host).to eq 'www.yammer.com'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#webserver_authorization_url" do
|
28
|
+
it "returns the authorization url" do
|
29
|
+
params = {
|
30
|
+
"client_id" => "PRbTcg9qjgKsp4jjpm1pw",
|
31
|
+
"redirect_uri" => "https://localhost/callback",
|
32
|
+
"response_type" =>"code",
|
33
|
+
"state" => "12345"
|
34
|
+
}
|
35
|
+
|
36
|
+
auth_url = subject.webserver_authorization_url(
|
37
|
+
:client_id => 'PRbTcg9qjgKsp4jjpm1pw',
|
38
|
+
:state => '12345',
|
39
|
+
:redirect_uri => 'https://localhost/callback'
|
40
|
+
)
|
41
|
+
|
42
|
+
parsed_url = Addressable::URI.parse(auth_url)
|
43
|
+
expect(parsed_url.path).to eq '/dialog/oauth/authorize'
|
44
|
+
expect(parsed_url.query_values).to eq params
|
45
|
+
expect(parsed_url.scheme).to eq 'https'
|
46
|
+
expect(parsed_url.host).to eq 'www.yammer.com'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#exchange_auth_code_for_token" do
|
51
|
+
it "makes a request to google oauth2 server" do
|
52
|
+
|
53
|
+
stub_request(:post, "https://www.yammer.com/oauth2/token").with(
|
54
|
+
:body => {
|
55
|
+
:grant_type => 'authorization_code',
|
56
|
+
:code => 'MmOGL795LbIZuJJVnL49Cc',
|
57
|
+
:redirect_uri => 'https://localhost',
|
58
|
+
:client_id => 'PRbTcg9qjgKsp4jjpm1pw',
|
59
|
+
:client_secret => 'a2nQpcUm2Dgq1chWdAvbXGTk'
|
60
|
+
},
|
61
|
+
:headers => {
|
62
|
+
'Accept' => "application/json",
|
63
|
+
'User-Agent' => "OAuth2 Ruby Gem #{OAuth2::Version}",
|
64
|
+
'Content-Type' => "application/x-www-form-urlencoded"
|
65
|
+
}
|
66
|
+
)
|
67
|
+
response = subject.exchange_auth_code_for_token(
|
68
|
+
:params => {
|
69
|
+
:code => 'MmOGL795LbIZuJJVnL49Cc',
|
70
|
+
:redirect_uri => 'https://localhost'
|
71
|
+
}
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|