oauth2-client 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.travis.yml +6 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +37 -0
- data/LICENSE +20 -0
- data/README.md +152 -0
- data/Rakefile +11 -0
- data/TODO +10 -0
- data/examples/google_client.rb +159 -0
- data/lib/oauth2.rb +7 -0
- data/lib/oauth2/client.rb +63 -0
- data/lib/oauth2/connection.rb +188 -0
- data/lib/oauth2/error.rb +3 -0
- data/lib/oauth2/grant.rb +7 -0
- data/lib/oauth2/grant/authorization_code.rb +71 -0
- data/lib/oauth2/grant/base.rb +41 -0
- data/lib/oauth2/grant/client_credentials.rb +27 -0
- data/lib/oauth2/grant/device.rb +37 -0
- data/lib/oauth2/grant/implicit.rb +46 -0
- data/lib/oauth2/grant/password.rb +28 -0
- data/lib/oauth2/grant/refresh_token.rb +26 -0
- data/lib/oauth2/helper.rb +46 -0
- data/lib/oauth2/version.rb +11 -0
- data/oauth2-client.gemspec +13 -0
- data/spec/.DS_Store +0 -0
- data/spec/examples/google_client_spec.rb +223 -0
- data/spec/mocks/oauth_client.yml +60 -0
- data/spec/oauth2/client_spec.rb +157 -0
- data/spec/oauth2/connection_spec.rb +273 -0
- data/spec/oauth2/grant/authorization_code_spec.rb +89 -0
- data/spec/oauth2/grant/base_spec.rb +57 -0
- data/spec/oauth2/grant/client_credentials_spec.rb +28 -0
- data/spec/oauth2/grant/device_spec.rb +35 -0
- data/spec/oauth2/grant/implicit_spec.rb +36 -0
- data/spec/oauth2/grant/password_spec.rb +28 -0
- data/spec/oauth2/grant/refresh_token_spec.rb +27 -0
- data/spec/spec_helper.rb +15 -0
- metadata +83 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module OAuth2
|
2
|
+
module Grant
|
3
|
+
class Password < Base
|
4
|
+
|
5
|
+
def grant_type
|
6
|
+
'password'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Retrieve an access token given the specified client.
|
10
|
+
#
|
11
|
+
# @param username
|
12
|
+
# @param password
|
13
|
+
# @param [Hash] params additional params
|
14
|
+
# @param [Hash] opts options
|
15
|
+
def get_token(username, password, opts={})
|
16
|
+
opts[:params] ||= {}
|
17
|
+
opts[:params].merge!({
|
18
|
+
:grant_type => grant_type,
|
19
|
+
:username => username,
|
20
|
+
:password => password
|
21
|
+
})
|
22
|
+
opts[:authenticate] ||= :headers
|
23
|
+
method = opts.delete(:method) || :post
|
24
|
+
make_request(method, @token_path, opts)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module OAuth2
|
2
|
+
module Grant
|
3
|
+
class RefreshToken < Base
|
4
|
+
|
5
|
+
def grant_type
|
6
|
+
'refresh_token'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Retrieve an access token for a given refresh token
|
10
|
+
#
|
11
|
+
# @param [String] refresh_token refresh token
|
12
|
+
# @param [Hash] params additional params
|
13
|
+
# @param [Hash] opts options
|
14
|
+
def get_token(refresh_token, opts={})
|
15
|
+
params = opts[:params] || {}
|
16
|
+
opts[:params] = params.merge!({
|
17
|
+
:grant_type => grant_type,
|
18
|
+
:refresh_token => refresh_token
|
19
|
+
})
|
20
|
+
opts[:authenticate] ||= :headers
|
21
|
+
method = opts.delete(:method) || :post
|
22
|
+
make_request(method, @token_path, opts)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
require 'addressable/uri'
|
4
|
+
module OAuth2
|
5
|
+
module UrlHelper
|
6
|
+
# convenience method to build response URI
|
7
|
+
def build_url(uri, opts={})
|
8
|
+
path = opts[:path] || ''
|
9
|
+
query = opts[:params] || {}
|
10
|
+
fragment = opts[:fragment] || {}
|
11
|
+
url = Addressable::URI.parse uri
|
12
|
+
url.path = path
|
13
|
+
url.query_values = query unless query.empty?
|
14
|
+
url.fragment = Addressable::URI.form_encode(fragment) unless fragment.empty?
|
15
|
+
url.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
# generates a random key of up to +size+ bytes. The value returned is Base64 encoded with non-word
|
19
|
+
# characters removed.
|
20
|
+
def generate_urlsafe_key(size=48)
|
21
|
+
seed = Time.now.to_i
|
22
|
+
size = size - seed.to_s.length
|
23
|
+
Base64.encode64("#{ OpenSSL::Random.random_bytes(size) }#{ seed }").gsub(/\W/, '')
|
24
|
+
end
|
25
|
+
alias_method :generate_nonce, :generate_urlsafe_key
|
26
|
+
|
27
|
+
def generate_timestamp #:nodoc:
|
28
|
+
Time.now.to_i.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def http_basic_encode(username, password)
|
32
|
+
encoded_data = ["#{username}:#{password}"].pack("m0")
|
33
|
+
"Basic #{encoded_data}"
|
34
|
+
end
|
35
|
+
module_function :http_basic_encode
|
36
|
+
|
37
|
+
# converts a hash to a URI query string
|
38
|
+
# @params [Hash] params URI parameters
|
39
|
+
def to_query(params)
|
40
|
+
unless params.is_a?(Hash)
|
41
|
+
raise "Expected Hash but got #{params.class.name}"
|
42
|
+
end
|
43
|
+
Addressable::URI.form_encode(params)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module OAuth2
|
2
|
+
class Version
|
3
|
+
MAJOR = 1 unless defined? OAuth2::Version::MAJOR
|
4
|
+
MINOR = 0 unless defined? OAuth2::Version::MINOR
|
5
|
+
PATCH = 0 unless defined? OAuth2::Version::PATCH
|
6
|
+
|
7
|
+
def self.to_s
|
8
|
+
[MAJOR, MINOR, PATCH].compact.join('.')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'oauth2-client'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.date = %q{2013-01-22}
|
5
|
+
s.summary = "OAuth2 Ruby Client"
|
6
|
+
s.description = "Create quick and dirty OAuth2 clients for many services. Google OAuth2 client included"
|
7
|
+
s.authors = ["Kevin Mutyaba"]
|
8
|
+
s.email = %q{tiabasnk@gmail.com}
|
9
|
+
s.homepage = ''
|
10
|
+
s.rubygems_version = %q{1.0.0}
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.require_paths = ['lib']
|
13
|
+
end
|
data/spec/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'google_client'
|
3
|
+
|
4
|
+
describe GoogleClient do
|
5
|
+
|
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
|
+
})
|
19
|
+
end
|
20
|
+
#
|
21
|
+
# https://developers.google.com/accounts/docs/OAuth2WebServer#formingtheurl
|
22
|
+
describe "#webserver_authorization_url" do
|
23
|
+
context "with scope as string" do
|
24
|
+
it "returns the authorization url" do
|
25
|
+
params = {
|
26
|
+
"approval_prompt" => "force",
|
27
|
+
"client_id" => "827502413694.apps.googleusercontent.com",
|
28
|
+
"redirect_uri" => "http://localhost",
|
29
|
+
"response_type" =>"code",
|
30
|
+
"scope" => "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
|
31
|
+
"state" => "/profile",
|
32
|
+
"access_type" => "offline"
|
33
|
+
}
|
34
|
+
|
35
|
+
auth_url = subject.webserver_authorization_url(
|
36
|
+
:scope => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
|
37
|
+
:state => '/profile',
|
38
|
+
:redirect_uri => 'http://localhost',
|
39
|
+
:approval_prompt => 'force',
|
40
|
+
:access_type => 'offline'
|
41
|
+
)
|
42
|
+
|
43
|
+
parsed_url = Addressable::URI.parse(auth_url)
|
44
|
+
expect(parsed_url.path).to eq '/o/oauth2/auth'
|
45
|
+
expect(parsed_url.query_values).to eq params
|
46
|
+
expect(parsed_url.scheme).to eq 'https'
|
47
|
+
expect(parsed_url.host).to eq 'accounts.google.com'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with scope as array" do
|
52
|
+
it "returns the authorization url" do
|
53
|
+
params = {
|
54
|
+
"approval_prompt"=>"force",
|
55
|
+
"client_id"=>"827502413694.apps.googleusercontent.com",
|
56
|
+
"redirect_uri"=>"http://localhost",
|
57
|
+
"response_type"=>"code",
|
58
|
+
"scope"=>"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
|
59
|
+
"state"=>"/profile"
|
60
|
+
}
|
61
|
+
|
62
|
+
auth_url = subject.webserver_authorization_url(
|
63
|
+
:scope => [
|
64
|
+
'https://www.googleapis.com/auth/userinfo.email',
|
65
|
+
'https://www.googleapis.com/auth/userinfo.profile'
|
66
|
+
],
|
67
|
+
:state => '/profile',
|
68
|
+
:redirect_uri => 'http://localhost',
|
69
|
+
:approval_prompt => 'force'
|
70
|
+
)
|
71
|
+
|
72
|
+
parsed_url = Addressable::URI.parse(auth_url)
|
73
|
+
expect(parsed_url.path).to eq '/o/oauth2/auth'
|
74
|
+
expect(parsed_url.query_values).to eq params
|
75
|
+
expect(parsed_url.scheme).to eq 'https'
|
76
|
+
expect(parsed_url.host).to eq 'accounts.google.com'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "scope neither array or string" do
|
81
|
+
it "raises and error" do
|
82
|
+
expect do
|
83
|
+
subject.webserver_authorization_url(
|
84
|
+
:scope => {},
|
85
|
+
:redirect_uri => 'https://oauth2-login-demo.appspot.com/code')
|
86
|
+
end.to raise_error
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#exchange_auth_code_for_token" do
|
92
|
+
it "makes a request to google oauth2 server" do
|
93
|
+
|
94
|
+
fake_response = double(
|
95
|
+
:code => '200',
|
96
|
+
:body => ''
|
97
|
+
)
|
98
|
+
|
99
|
+
Net::HTTP.any_instance.should_receive(:post).with(
|
100
|
+
"/o/oauth2/token",
|
101
|
+
"redirect_uri=https%3A%2F%2Flocalhost&code=4%2FdbB0-UD1cvrQg2EuEFtRtHwPEmvR.IrScsjgB5M4VuJJVnL49Cc8QdUjRdAI",
|
102
|
+
{
|
103
|
+
"Accept"=>"application/json",
|
104
|
+
"User-Agent"=>"GoOAuth2 0.1",
|
105
|
+
"Authorization"=>"Basic ODI3NTAyNDEzNjk0LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tOmEyblFwY1VtMkRncTFjaFdkQXZiWEdUaw==",
|
106
|
+
"Content-Type"=>"application/x-www-form-urlencoded"
|
107
|
+
}
|
108
|
+
).and_return(fake_response)
|
109
|
+
|
110
|
+
subject.exchange_auth_code_for_token(
|
111
|
+
:params => {
|
112
|
+
:code => '4/dbB0-UD1cvrQg2EuEFtRtHwPEmvR.IrScsjgB5M4VuJJVnL49Cc8QdUjRdAI',
|
113
|
+
:redirect_uri => 'https://localhost'
|
114
|
+
}
|
115
|
+
)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#client_authorization_url" do
|
120
|
+
it "returns url string for obtaining authorization" do
|
121
|
+
params = {
|
122
|
+
"approval_prompt" => "force",
|
123
|
+
"client_id" => "827502413694.apps.googleusercontent.com",
|
124
|
+
"redirect_uri" => "https://oauth2-login-demo.appspot.com/token",
|
125
|
+
"response_type" => "token",
|
126
|
+
"scope" => "https://www.googleapis.com/auth/userinfo.email",
|
127
|
+
"state" => "/profile"
|
128
|
+
}
|
129
|
+
|
130
|
+
auth_url = subject.clientside_authorization_url(
|
131
|
+
:scope => 'https://www.googleapis.com/auth/userinfo.email',
|
132
|
+
:state => '/profile',
|
133
|
+
:redirect_uri => 'https://oauth2-login-demo.appspot.com/token',
|
134
|
+
:approval_prompt => 'force'
|
135
|
+
)
|
136
|
+
|
137
|
+
parsed_url = Addressable::URI.parse(auth_url)
|
138
|
+
expect(parsed_url.path).to eq '/o/oauth2/auth'
|
139
|
+
expect(parsed_url.query_values).to eq params
|
140
|
+
expect(parsed_url.scheme).to eq 'https'
|
141
|
+
expect(parsed_url.host).to eq 'accounts.google.com'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#refresh_token" do
|
146
|
+
it "makes a request to google to obtain new token" do
|
147
|
+
fake_response = double(
|
148
|
+
:code => '200',
|
149
|
+
:body => ''
|
150
|
+
)
|
151
|
+
|
152
|
+
Net::HTTP.any_instance.should_receive(:post).with(
|
153
|
+
"/o/oauth2/token",
|
154
|
+
"state=%2Fprofile&grant_type=refresh_token&refresh_token=2YotnFZFEjr1zCsicMWpAA",
|
155
|
+
{
|
156
|
+
"Accept" => "application/json",
|
157
|
+
"User-Agent" => "GoOAuth2 0.1",
|
158
|
+
"Authorization" => "Basic ODI3NTAyNDEzNjk0LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tOmEyblFwY1VtMkRncTFjaFdkQXZiWEdUaw==",
|
159
|
+
"Content-Type" => "application/x-www-form-urlencoded"
|
160
|
+
}
|
161
|
+
).and_return(fake_response)
|
162
|
+
|
163
|
+
subject.refresh_access_token(
|
164
|
+
:params => {
|
165
|
+
:state => '/profile',
|
166
|
+
:refresh_token => '2YotnFZFEjr1zCsicMWpAA'
|
167
|
+
}
|
168
|
+
)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "#get_device_code" do
|
173
|
+
it "makes a request to google to obtain a device code" do
|
174
|
+
fake_response = double(
|
175
|
+
:code => '200',
|
176
|
+
:body => ''
|
177
|
+
)
|
178
|
+
|
179
|
+
Net::HTTP.any_instance.should_receive(:post).with(
|
180
|
+
"/o/oauth2/device/code",
|
181
|
+
"scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&client_id=827502413694.apps.googleusercontent.com",
|
182
|
+
{
|
183
|
+
"Accept"=>"application/json",
|
184
|
+
"User-Agent"=>"GoOAuth2 0.1",
|
185
|
+
"Content-Type"=>"application/x-www-form-urlencoded"
|
186
|
+
}
|
187
|
+
).and_return(fake_response)
|
188
|
+
|
189
|
+
subject.get_device_code(
|
190
|
+
:params => {
|
191
|
+
:scope => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
|
192
|
+
}
|
193
|
+
)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "#exchange_device_code_for_token" do
|
198
|
+
it "makes request to google to obtain an access token" do
|
199
|
+
fake_response = double(
|
200
|
+
:code => '200',
|
201
|
+
:body => ''
|
202
|
+
)
|
203
|
+
|
204
|
+
Net::HTTP.any_instance.should_receive(:post).with(
|
205
|
+
"/o/oauth2/token",
|
206
|
+
"state=%2Fprofile&code=G3Y6jU3a&grant_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fdevice%2F1.0",
|
207
|
+
{
|
208
|
+
"Accept"=>"application/json",
|
209
|
+
"User-Agent" => "GoOAuth2 0.1",
|
210
|
+
"Authorization"=>"Basic ODI3NTAyNDEzNjk0LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tOmEyblFwY1VtMkRncTFjaFdkQXZiWEdUaw==",
|
211
|
+
"Content-Type"=>"application/x-www-form-urlencoded"
|
212
|
+
}
|
213
|
+
).and_return(fake_response)
|
214
|
+
|
215
|
+
subject.exchange_device_code_for_token(
|
216
|
+
:params => {
|
217
|
+
:state => '/profile',
|
218
|
+
:code => 'G3Y6jU3a'
|
219
|
+
}
|
220
|
+
)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
test:
|
2
|
+
google:
|
3
|
+
client_id: '827502413694.apps.googleusercontent.com'
|
4
|
+
client_secret: 'a2nQpcUm2Dgq1chWdAvbXGTk'
|
5
|
+
host: accounts.google.com
|
6
|
+
port: 443
|
7
|
+
token_path: /o/oauth2/token
|
8
|
+
authorize_path: /o/oauth2/auth
|
9
|
+
device_path: /o/oauth2/device/code
|
10
|
+
http_client: #OAuth2Client::Connection
|
11
|
+
max_redirects: 5
|
12
|
+
ssl:
|
13
|
+
|
14
|
+
yammer:
|
15
|
+
client_id: 'PRbTcg9qjgKsp4jjpm1pw'
|
16
|
+
client_secret: 'Xn7kp7Ly0TCY4GtZWkmSsqGEPg10DmMADyjWkf2U'
|
17
|
+
host: www.yammer.com
|
18
|
+
port: 443
|
19
|
+
token_path: /oauth2/access_token
|
20
|
+
authorize_path: /dialog/oauth/
|
21
|
+
device_path:
|
22
|
+
http_client: #OAuth2Client::Connection
|
23
|
+
max_redirects: 5
|
24
|
+
ssl: #
|
25
|
+
|
26
|
+
microsoft:
|
27
|
+
client_id: 'PRbTcg9qjgKsp4jjpm1pw'
|
28
|
+
client_secret: 'Xn7kp7Ly0TCY4GtZWkmSsqGEPg10DmMADyjWkf2U'
|
29
|
+
host: login.live.com
|
30
|
+
port: 443
|
31
|
+
token_path: /oauth20_token.srf
|
32
|
+
authorize_path: /oauth20_authorize.srf
|
33
|
+
device_path:
|
34
|
+
http_client: #OAuth2Client::Connection
|
35
|
+
max_redirects: 5
|
36
|
+
ssl: #
|
37
|
+
|
38
|
+
github:
|
39
|
+
client_id: '2945e6425da3d5d17ffc'
|
40
|
+
client_secret: '0a8f686f2835a70a79dbcece2ec63bc5079f40a8'
|
41
|
+
host: github.com
|
42
|
+
port: 443
|
43
|
+
token_path: /login/oauth/access_token
|
44
|
+
authorize_path: /login/oauth/authorize
|
45
|
+
device_path:
|
46
|
+
http_client: #OAuth2Client::Connection
|
47
|
+
max_redirects: 5
|
48
|
+
ssl: #
|
49
|
+
|
50
|
+
foursquare:
|
51
|
+
client_id: '2945e6425da3d5d17ffc'
|
52
|
+
client_secret: '0a8f686f2835a70a79dbcece2ec63bc5079f40a8'
|
53
|
+
host: foursquare.com
|
54
|
+
port: 443
|
55
|
+
token_path: /oauth2/access_token
|
56
|
+
authorize_path: /oauth2/authenticate
|
57
|
+
device_path:
|
58
|
+
http_client: #OAuth2Client::Connection
|
59
|
+
max_redirects: 5
|
60
|
+
ssl: #
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe OAuth2::Client do
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
@client_id= 's6BhdRkqt3'
|
8
|
+
@client_secret = '4hJZY88TCBB9q8IpkeualA2lZsUhOSclkkSKw3RXuE'
|
9
|
+
@host = 'example.com'
|
10
|
+
@client = OAuth2::Client.new(@host, @client_id, @client_secret)
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { @client }
|
14
|
+
|
15
|
+
context "with default options" do
|
16
|
+
describe "#token_path" do
|
17
|
+
it "returns " do
|
18
|
+
expect(subject.token_path).to eq '/oauth2/token'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#authorize_path" do
|
23
|
+
it "returns " do
|
24
|
+
expect(subject.authorize_path).to eq '/oauth2/authorize'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#device_path" do
|
29
|
+
it "returns " do
|
30
|
+
expect(subject.device_path).to eq '/oauth2/device/code'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with custom options" do
|
36
|
+
subject do
|
37
|
+
OAuth2::Client.new(@host, @client_id, @client_secret, {
|
38
|
+
:token_path => '/o/v2/token',
|
39
|
+
:authorize_path => '/o/v2/authorize',
|
40
|
+
:device_path => '/o/v2/device/code'
|
41
|
+
})
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#token_path" do
|
45
|
+
it "returns token path" do
|
46
|
+
expect(subject.token_path).to eq '/o/v2/token'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#authorize_path" do
|
51
|
+
it "returns authorize path" do
|
52
|
+
expect(subject.authorize_path).to eq '/o/v2/authorize'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#device_path" do
|
57
|
+
it "returns device path" do
|
58
|
+
expect(subject.device_path).to eq '/o/v2/device/code'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "host" do
|
64
|
+
it "returns host" do
|
65
|
+
expect(subject.host).to eq 'example.com'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "host=" do
|
70
|
+
before do
|
71
|
+
subject.host = 'elpmaxe.com'
|
72
|
+
end
|
73
|
+
|
74
|
+
it "set the connection to nil" do
|
75
|
+
expect(subject.instance_variable_get(:'@connection')).to eq nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sets new host on client" do
|
79
|
+
expect(subject.host).to eq 'elpmaxe.com'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#connection_options" do
|
84
|
+
context "with default connection options" do
|
85
|
+
it "returns empty hash" do
|
86
|
+
expect(subject.connection_options).to eq ({})
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "with custom connection options" do
|
91
|
+
it "returns default options" do
|
92
|
+
subject.connection_options = { :max_redirects => 10, :use_ssl => true }
|
93
|
+
expect(subject.connection_options).to eq ({:max_redirects => 10, :use_ssl => true})
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#implicit" do
|
99
|
+
it "returns implicit grant object" do
|
100
|
+
expect(@client.implicit).to be_instance_of(OAuth2::Grant::Implicit)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#authorization_code" do
|
105
|
+
it "returns authorization code grant" do
|
106
|
+
expect(@client.authorization_code).to be_instance_of(OAuth2::Grant::AuthorizationCode)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#refresh_token" do
|
111
|
+
it "returns refresh token grant" do
|
112
|
+
expect(@client.refresh_token).to be_instance_of(OAuth2::Grant::RefreshToken)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#client_credentials" do
|
117
|
+
it "returns client credentials grant" do
|
118
|
+
expect(@client.client_credentials).to be_instance_of(OAuth2::Grant::ClientCredentials)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "#password" do
|
123
|
+
it "returns password grant" do
|
124
|
+
expect(@client.password).to be_instance_of(OAuth2::Grant::Password)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "" do
|
129
|
+
it "returns device code grant" do
|
130
|
+
expect(@client.device_code).to be_instance_of(OAuth2::Grant::DeviceCode)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
describe "#implicit" do
|
136
|
+
it "returns implicit grant object" do
|
137
|
+
expect(subject.implicit).to be_instance_of(OAuth2::Grant::Implicit)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#connection" do
|
142
|
+
context "with default connection options" do
|
143
|
+
it "returns HttpConnection" do
|
144
|
+
expect(subject.send(:connection)).to be_instance_of(OAuth2::HttpConnection)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "with custom connection options" do
|
149
|
+
it "returns custom connection" do
|
150
|
+
# custom_http = Struct.new('CustomHttpClient')
|
151
|
+
# conn_options = { :connection_client => custom_http }
|
152
|
+
# oauth_client = OAuth2::Client.new('example.com', @client_id, @client_secret, conn_options)
|
153
|
+
# expect(oauth_client.send(:connection)).to be_instance_of custom_http
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|