signet 0.15.0 → 0.16.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.
@@ -1,1254 +0,0 @@
1
- # Copyright (C) 2010 Google Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- require "spec_helper"
15
- require "signet/oauth_2/client"
16
- require "openssl"
17
- require "jwt"
18
- require "date"
19
-
20
- conn = Faraday.default_connection
21
-
22
- def build_json_response payload
23
- [200, { "Content-Type" => "application/json; charset=utf-8" }, MultiJson.dump(payload)]
24
- end
25
-
26
- def build_form_encoded_response payload
27
- [200, { "Content-Type" => "application/json; charset=utf-8" }, Addressable::URI.form_encode(payload)]
28
- end
29
-
30
- describe Signet::OAuth2::Client, "unconfigured" do
31
- before do
32
- @client = Signet::OAuth2::Client.new
33
- end
34
- it "should allow additional paraemters to be set." do
35
- @client.additional_parameters["type"] = "web_server"
36
- expect(@client.additional_parameters).to eq({ "type" => "web_server" })
37
- end
38
- it "should raise an error if a bogus scope is provided" do
39
- expect(lambda do
40
- @client = Signet::OAuth2::Client.new scope: :bogus
41
- end).to raise_error(TypeError)
42
- end
43
-
44
- it "should raise an error if a scope array is provided with spaces" do
45
- expect(lambda do
46
- @client = Signet::OAuth2::Client.new(
47
- scope: ["legit", "bogus bogus"]
48
- )
49
- end).to raise_error(ArgumentError)
50
- end
51
-
52
- it "should allow the scope to be set to a String" do
53
- @client.scope = "legit"
54
- expect(@client.scope).to eq ["legit"]
55
- @client.scope = "legit alsolegit"
56
- expect(@client.scope).to eq ["legit", "alsolegit"]
57
- end
58
-
59
- it "should allow the scope to be set to an Array" do
60
- @client.scope = ["legit"]
61
- expect(@client.scope).to eq ["legit"]
62
- @client.scope = ["legit", "alsolegit"]
63
- expect(@client.scope).to eq ["legit", "alsolegit"]
64
- end
65
-
66
- it "should raise an error if a bogus redirect URI is provided" do
67
- expect(lambda do
68
- @client = Signet::OAuth2::Client.new redirect_uri: :bogus
69
- end).to raise_error(TypeError)
70
- end
71
-
72
- it "should raise an error if a relative redirect URI is provided" do
73
- expect(lambda do
74
- @client = Signet::OAuth2::Client.new redirect_uri: "/relative/path"
75
- end).to raise_error(ArgumentError)
76
- end
77
-
78
- it 'should allow "postmessage" as a redirect URI (Google hack)' do
79
- @client.authorization_uri = "https://example.com/authorize"
80
- @client.client_id = "s6BhdRkqt3"
81
- @client.redirect_uri = "postmessage"
82
- expect(@client.authorization_uri.query_values["redirect_uri"]).to eq "postmessage"
83
- end
84
-
85
- it "should allow oob values as a redirect URI (for installed apps)" do
86
- @client.authorization_uri = "https://example.com/authorize"
87
- @client.client_id = "s6BhdRkqt3"
88
- @client.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
89
- expect(@client.authorization_uri.query_values["redirect_uri"]).to eq "urn:ietf:wg:oauth:2.0:oob"
90
- @client.redirect_uri = "oob"
91
- expect(@client.authorization_uri.query_values["redirect_uri"]).to eq "oob"
92
- end
93
-
94
- it "should have no authorization_uri" do
95
- expect(@client.authorization_uri).to eq nil
96
- end
97
-
98
- it "should allow the authorization_uri to be set to a String" do
99
- @client.authorization_uri = "https://example.com/authorize"
100
- @client.client_id = "s6BhdRkqt3"
101
- @client.redirect_uri = "https://example.client.com/callback"
102
- expect(@client.authorization_uri.to_s).to include(
103
- "https://example.com/authorize"
104
- )
105
- expect(@client.authorization_uri.query_values["client_id"]).to eq "s6BhdRkqt3"
106
- expect(@client.authorization_uri.query_values["redirect_uri"]).to eq(
107
- "https://example.client.com/callback"
108
- )
109
- end
110
-
111
- it "should allow the authorization_uri to be set to a Hash" do
112
- @client.authorization_uri = {
113
- scheme: "https", host: "example.com", path: "/authorize"
114
- }
115
- @client.client_id = "s6BhdRkqt3"
116
- @client.redirect_uri = "https://example.client.com/callback"
117
- expect(@client.authorization_uri.to_s).to include(
118
- "https://example.com/authorize"
119
- )
120
- expect(@client.authorization_uri.query_values["client_id"]).to eq "s6BhdRkqt3"
121
- expect(@client.authorization_uri.query_values["redirect_uri"]).to eq(
122
- "https://example.client.com/callback"
123
- )
124
- end
125
-
126
- it "should allow the authorization_uri to be set to a URI" do
127
- @client.authorization_uri =
128
- Addressable::URI.parse "https://example.com/authorize"
129
- @client.client_id = "s6BhdRkqt3"
130
- @client.redirect_uri =
131
- Addressable::URI.parse "https://example.client.com/callback"
132
- expect(@client.authorization_uri.to_s).to include(
133
- "https://example.com/authorize"
134
- )
135
- expect(@client.authorization_uri.query_values["client_id"]).to eq "s6BhdRkqt3"
136
- expect(@client.authorization_uri.query_values["redirect_uri"]).to eq(
137
- "https://example.client.com/callback"
138
- )
139
- end
140
-
141
- it "should require a redirect URI when getting the authorization_uri" do
142
- @client.authorization_uri =
143
- Addressable::URI.parse "https://example.com/authorize"
144
- @client.client_id = "s6BhdRkqt3"
145
- expect(lambda do
146
- @client.authorization_uri
147
- end).to raise_error(ArgumentError)
148
- end
149
-
150
- it "should require a client ID when getting the authorization_uri" do
151
- @client.authorization_uri =
152
- Addressable::URI.parse "https://example.com/authorize"
153
- @client.redirect_uri =
154
- Addressable::URI.parse "https://example.client.com/callback"
155
- expect(lambda do
156
- @client.authorization_uri
157
- end).to raise_error(ArgumentError)
158
- end
159
-
160
- it "should have no token_credential_uri" do
161
- expect(@client.token_credential_uri).to eq nil
162
- end
163
-
164
- it "should allow the token_credential_uri to be set to a String" do
165
- @client.token_credential_uri = "https://example.com/token"
166
- expect(@client.token_credential_uri.to_s).to eq "https://example.com/token"
167
- end
168
-
169
- it "should allow the token_credential_uri to be set to a Hash" do
170
- @client.token_credential_uri = {
171
- scheme: "https", host: "example.com", path: "/token"
172
- }
173
- expect(@client.token_credential_uri.to_s).to eq "https://example.com/token"
174
- end
175
-
176
- it "should allow the token_credential_uri to be set to a URI" do
177
- @client.token_credential_uri =
178
- Addressable::URI.parse "https://example.com/token"
179
- expect(@client.token_credential_uri.to_s).to eq "https://example.com/token"
180
- end
181
- end
182
-
183
- describe Signet::OAuth2::Client, "configured for assertions profile" do
184
- describe "when using RSA keys" do
185
- before do
186
- @key = OpenSSL::PKey::RSA.new 2048
187
- @client = Signet::OAuth2::Client.new(
188
- token_credential_uri: "https://oauth2.googleapis.com/token",
189
- scope: "https://www.googleapis.com/auth/userinfo.profile",
190
- issuer: "app@example.com",
191
- audience: "https://oauth2.googleapis.com/token",
192
- signing_key: @key
193
- )
194
- end
195
-
196
- it "should generate valid JWTs" do
197
- jwt = @client.to_jwt
198
- expect(jwt).not_to be_nil
199
-
200
- claim, header = JWT.decode jwt, @key.public_key, true, algorithm: "RS256"
201
- expect(claim["iss"]).to eq "app@example.com"
202
- expect(claim["scope"]).to eq "https://www.googleapis.com/auth/userinfo.profile"
203
- expect(claim["aud"]).to eq "https://oauth2.googleapis.com/token"
204
- end
205
-
206
- it "should generate valid JWTs for impersonation" do
207
- @client.principal = "user@example.com"
208
- jwt = @client.to_jwt
209
- expect(jwt).not_to be_nil
210
-
211
- claim, header = JWT.decode jwt, @key.public_key, true, algorithm: "RS256"
212
- expect(claim["iss"]).to eq "app@example.com"
213
- expect(claim["prn"]).to eq "user@example.com"
214
- expect(claim["scope"]).to eq "https://www.googleapis.com/auth/userinfo.profile"
215
- expect(claim["aud"]).to eq "https://oauth2.googleapis.com/token"
216
- end
217
-
218
- it "should generate valid JWTs for impersonation using deprecated person attribute" do
219
- @client.person = "user@example.com"
220
- jwt = @client.to_jwt
221
- expect(jwt).not_to be_nil
222
-
223
- claim, header = JWT.decode jwt, @key.public_key, true, algorithm: "RS256"
224
- expect(claim["iss"]).to eq "app@example.com"
225
- expect(claim["prn"]).to eq "user@example.com"
226
- expect(claim["scope"]).to eq "https://www.googleapis.com/auth/userinfo.profile"
227
- expect(claim["aud"]).to eq "https://oauth2.googleapis.com/token"
228
- end
229
-
230
- it "should generate valid JWTs for impersonation using the sub attribute" do
231
- @client.sub = "user@example.com"
232
- jwt = @client.to_jwt
233
- expect(jwt).not_to be_nil
234
-
235
- claim, header = JWT.decode jwt, @key.public_key, true, algorithm: "RS256"
236
- expect(claim["iss"]).to eq "app@example.com"
237
- expect(claim["sub"]).to eq "user@example.com"
238
- expect(claim["scope"]).to eq "https://www.googleapis.com/auth/userinfo.profile"
239
- expect(claim["aud"]).to eq "https://oauth2.googleapis.com/token"
240
- end
241
-
242
- it "should generate a JSON representation of the client" do
243
- @client.principal = "user@example.com"
244
- json = @client.to_json
245
- expect(json).not_to be_nil
246
-
247
- deserialized = MultiJson.load json
248
- expect(deserialized["token_credential_uri"]).to eq "https://oauth2.googleapis.com/token"
249
- expect(deserialized["scope"]).to eq ["https://www.googleapis.com/auth/userinfo.profile"]
250
- expect(deserialized["issuer"]).to eq "app@example.com"
251
- expect(deserialized["audience"]).to eq "https://oauth2.googleapis.com/token"
252
- expect(deserialized["signing_key"]).to eq @key.to_s
253
- end
254
-
255
- it "should send valid access token request" do
256
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
257
- stub.post "/token" do |env|
258
- params = Addressable::URI.form_unencode env[:body]
259
- claim, header = JWT.decode params.assoc("assertion").last, @key.public_key, true, algorithm: "RS256"
260
- expect(params.assoc("grant_type")).to eq ["grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"]
261
- build_json_response(
262
- "access_token" => "1/abcdef1234567890",
263
- "token_type" => "Bearer",
264
- "expires_in" => 3600
265
- )
266
- end
267
- end
268
- connection = Faraday.new url: "https://www.google.com" do |builder|
269
- builder.adapter :test, stubs
270
- end
271
-
272
- @client.fetch_access_token! connection: connection
273
- expect(@client.access_token).to eq "1/abcdef1234567890"
274
- stubs.verify_stubbed_calls
275
- end
276
- end
277
-
278
- describe "when using shared secrets" do
279
- before do
280
- @key = "my secret key"
281
- @client = Signet::OAuth2::Client.new(
282
- token_credential_uri: "https://oauth2.googleapis.com/token",
283
- scope: "https://www.googleapis.com/auth/userinfo.profile",
284
- issuer: "app@example.com",
285
- audience: "https://oauth2.googleapis.com/token",
286
- signing_key: @key
287
- )
288
- end
289
-
290
- it "should generate valid JWTs" do
291
- jwt = @client.to_jwt
292
- expect(jwt).not_to be_nil
293
-
294
- claim, header = JWT.decode jwt, @key, true, algorithm: "HS256"
295
- expect(claim["iss"]).to eq "app@example.com"
296
- expect(claim["scope"]).to eq "https://www.googleapis.com/auth/userinfo.profile"
297
- expect(claim["aud"]).to eq "https://oauth2.googleapis.com/token"
298
- end
299
- end
300
- end
301
-
302
- describe Signet::OAuth2::Client, "configured for Google userinfo API" do
303
- before do
304
- @client = Signet::OAuth2::Client.new(
305
- authorization_uri: "https://accounts.google.com/o/oauth2/auth",
306
- token_credential_uri: "https://oauth2.googleapis.com/token",
307
- scope: "https://www.googleapis.com/auth/userinfo.profile"
308
- )
309
- end
310
-
311
- it "should not have a grant type by default" do
312
- expect(@client.grant_type).to eq nil
313
- end
314
-
315
- it "should use the authorization_code grant type if given code" do
316
- @client.code = "00000"
317
- @client.redirect_uri = "http://www.example.com/"
318
- expect(@client.grant_type).to eq "authorization_code"
319
- end
320
-
321
- it "should use the refresh_token grant type if given refresh token" do
322
- @client.refresh_token = "54321"
323
- expect(@client.grant_type).to eq "refresh_token"
324
- end
325
-
326
- it "should use the password grant type if given username and password" do
327
- @client.username = "johndoe"
328
- @client.password = "incognito"
329
- expect(@client.grant_type).to eq "password"
330
- end
331
-
332
- it "should allow the grant type to be set manually" do
333
- @client.grant_type = "authorization_code"
334
- expect(@client.grant_type).to eq "authorization_code"
335
- @client.grant_type = "refresh_token"
336
- expect(@client.grant_type).to eq "refresh_token"
337
- @client.grant_type = "password"
338
- expect(@client.grant_type).to eq "password"
339
- end
340
-
341
- it "should allow the grant type to be set to an extension" do
342
- @client.grant_type = "urn:ietf:params:oauth:grant-type:saml2-bearer"
343
- @client.extension_parameters["assertion"] =
344
- "PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU"
345
-
346
- expect(@client.grant_type).to eq Addressable::URI.parse("urn:ietf:params:oauth:grant-type:saml2-bearer")
347
- expect(@client.extension_parameters).to eq ({ "assertion" => "PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU" })
348
- end
349
-
350
- it "should raise an error if extension parameters are bogus" do
351
- expect(lambda do
352
- @client.extension_parameters = :bogus
353
- end).to raise_error(TypeError)
354
- end
355
-
356
- it "should include extension parameters in token request" do
357
- @client.grant_type = "urn:ietf:params:oauth:grant-type:saml2-bearer"
358
- @client.extension_parameters["assertion"] =
359
- "PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU"
360
-
361
- request = @client.generate_access_token_request
362
- expect(request).to include("assertion" => "PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU")
363
- end
364
-
365
- it "should include the scope in token request" do
366
- @client.scope = ["https://www.googleapis.com/auth/userinfo.profile"]
367
-
368
- request = @client.generate_access_token_request use_configured_scope: true
369
- expect(request).to include("scope" => ["https://www.googleapis.com/auth/userinfo.profile"])
370
- end
371
-
372
- it "should allow the token to be updated" do
373
- issued_at = Time.now
374
- @client.update_token!(
375
- :access_token => "12345",
376
- refresh_token: "54321",
377
- :expires_in => 3600,
378
- :issued_at => issued_at
379
- )
380
- expect(@client.access_token).to eq "12345"
381
- expect(@client.refresh_token).to eq "54321"
382
- expect(@client.expires_in).to eq 3600
383
- expect(@client.issued_at).to eq issued_at
384
- expect(@client).to_not be_expired
385
- end
386
-
387
- it "should handle expires as equivalent to expires_in" do
388
- issued_at = Time.now
389
- @client.update_token!(
390
- :access_token => "12345",
391
- refresh_token: "54321",
392
- :expires => 600,
393
- :issued_at => issued_at
394
- )
395
- expect(@client.expires_in).to eq 600
396
- end
397
-
398
- it "should allow the token to be updated without an expiration" do
399
- @client.update_token!(
400
- :access_token => "12345",
401
- refresh_token: "54321"
402
- )
403
- expect(@client.access_token).to eq "12345"
404
- expect(@client.refresh_token).to eq "54321"
405
- expect(@client.expires_in).to eq nil
406
- expect(@client.issued_at).to eq nil
407
- expect(@client).to_not be_expired
408
- end
409
-
410
- it "should allow the token expiration to be cleared" do
411
- issued_at = Time.now
412
- @client.update_token!(
413
- :access_token => "12345",
414
- refresh_token: "54321",
415
- :expires_in => 3600,
416
- :issued_at => issued_at
417
- )
418
- @client.expires_in = nil
419
- @client.issued_at = nil
420
- expect(@client).to_not be_expired
421
- end
422
-
423
- it "should allow the expires_at time to be updated" do
424
- expires_at = Time.now
425
- @client.update_token!(
426
- expires_at: expires_at.to_i,
427
- expires_in: nil
428
- )
429
- expect(@client.expires_at).to be_within(1).of(expires_at)
430
- expect(@client).to be_expired
431
- end
432
-
433
- it "should calculate the expires_at from issued_at when issued_at is set" do
434
- expires_in = 3600
435
- issued_at = Time.now - expires_in
436
- @client.update_token!(
437
- :issued_at => issued_at,
438
- expires_in: expires_in
439
- )
440
- expect(@client.expires_at).to eq issued_at + expires_in
441
- expect(@client).to be_expired
442
- end
443
-
444
- it "should calculate expires_at from Time.now when issed_at is NOT set" do
445
- expires_in = 3600
446
- expires_at = Time.now + expires_in
447
- @client.update_token! expires_in: expires_in
448
- expect(@client.expires_at).to be_within(1).of(expires_at)
449
- expect(@client).to_not be_expired
450
- end
451
-
452
- # This test is to document the way that expires_in has always been used:
453
- # If expires_in is set on the client, it always resets the issued_at time
454
- # to Time.now
455
- it "sets issued_at to Time.now when expires_in is not set through update_token!" do
456
- one_hour = 3600
457
- issued_at = Time.now - (2 * one_hour)
458
- current_time = Time.now
459
-
460
- @client.issued_at = issued_at
461
- @client.expires_in = one_hour
462
-
463
- expect(@client.issued_at).to_not eq issued_at
464
- expect(@client.issued_at).to be_within(1).of(current_time)
465
- expect(@client).to_not be_expired
466
- end
467
-
468
- it "should allow setting expires_at manually" do
469
- expires_at = Time.now + 100
470
- @client.expires_at = expires_at.to_i
471
- expect(@client.expires_at).to be_within(1).of(expires_at)
472
- expect(@client).to_not be_expired
473
- end
474
-
475
- it "should normalize values of expires_at to instances of time" do
476
- time_formats = [DateTime.new, "12:00", 100, Time.new]
477
- normalized_time_formats = []
478
- time_formats.each do |time|
479
- @client.expires_at = time
480
- normalized_time_formats << @client.expires_at
481
- end
482
- normalized_time_formats.each do |time|
483
- expect(time).to be_an_instance_of(Time)
484
- end
485
- end
486
-
487
- it "should set expires_in when expires_at is set" do
488
- issued_at = Time.now
489
- expires_at = Time.now + 100
490
- @client.expires_at = expires_at.to_i
491
- @client.issued_at = issued_at
492
- expect(@client.expires_in).to be_within(1).of (expires_at - issued_at).to_i
493
- @client.expires_at = nil
494
- expect(@client.expires_in).to be_nil
495
- end
496
-
497
- it "should set expires_in to nil when expires_at is set to nil" do
498
- @client.expires_at = nil
499
- expect(@client.expires_in).to be_nil
500
- end
501
-
502
- it "should set expires_at when expires_in is set" do
503
- expires_in = 100
504
- @client.expires_in = expires_in
505
- expect(@client.expires_at).to eq (@client.issued_at + expires_in)
506
- @client.expires_in = nil
507
- expect(@client.expires_at).to be_nil
508
- end
509
-
510
- it "should set expires_at to nil when expires_in is set to nil" do
511
- @client.expires_in = nil
512
- expect(@client.expires_at).to be_nil
513
- end
514
-
515
- it "should indicate the token is not expired if expired_at nil" do
516
- @client.expires_at = nil
517
- expect(@client.expires_within?(60)).to be false
518
- expect(@client.expired?).to be false
519
- end
520
-
521
- it "should indicate the token is not expiring when expiry beyond window" do
522
- @client.expires_at = Time.now + 100
523
- expect(@client.expires_within?(60)).to be false
524
- end
525
-
526
- it "should indicate the token is expiring soon when expiry within window" do
527
- @client.expires_at = Time.now + 30
528
- expect(@client.expires_within?(60)).to be true
529
- end
530
-
531
- it "should raise an error if the authorization endpoint is not secure" do
532
- @client.client_id = "client-12345"
533
- @client.client_secret = "secret-12345"
534
- @client.redirect_uri = "http://www.example.com/"
535
- @client.authorization_uri = "http://accounts.google.com/o/oauth2/auth"
536
- expect(lambda do
537
- @client.authorization_uri
538
- end).to raise_error(Signet::UnsafeOperationError)
539
- end
540
-
541
- it "should raise an error if token credential URI is missing" do
542
- @client.token_credential_uri = nil
543
- expect(lambda do
544
- @client.fetch_access_token!
545
- end).to raise_error(ArgumentError)
546
- end
547
-
548
- it "should raise an error if unauthorized" do
549
- @client.client_id = "client-12345"
550
- @client.client_secret = "secret-12345"
551
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
552
- stub.post "/token" do
553
- [401, {}, "User authorization failed or something."]
554
- end
555
- end
556
- expect(lambda do
557
- connection = Faraday.new url: "https://www.google.com" do |builder|
558
- builder.adapter :test, stubs
559
- end
560
- @client.fetch_access_token!(
561
- connection: connection
562
- )
563
- end).to raise_error(Signet::AuthorizationError)
564
- stubs.verify_stubbed_calls
565
- end
566
-
567
- it "should raise a remote server error if the server gives a 5xx status" do
568
- @client.client_id = "client-12345"
569
- @client.client_secret = "secret-12345"
570
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
571
- stub.post "/token" do
572
- [509, {}, "Rate limit hit or something."]
573
- end
574
- end
575
- expect(lambda do
576
- connection = Faraday.new url: "https://www.google.com" do |builder|
577
- builder.adapter :test, stubs
578
- end
579
- @client.fetch_access_token!(
580
- connection: connection
581
- )
582
- end).to raise_error(Signet::RemoteServerError)
583
- stubs.verify_stubbed_calls
584
- end
585
-
586
- it "should raise an unexpected error if the token server gives an unexpected status" do
587
- @client.client_id = "client-12345"
588
- @client.client_secret = "secret-12345"
589
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
590
- stub.post "/token" do
591
- [309, {}, "Rate limit hit or something."]
592
- end
593
- end
594
- expect(lambda do
595
- connection = Faraday.new url: "https://www.google.com" do |builder|
596
- builder.adapter :test, stubs
597
- end
598
- @client.fetch_access_token!(
599
- connection: connection
600
- )
601
- end).to raise_error(Signet::UnexpectedStatusError)
602
- stubs.verify_stubbed_calls
603
- end
604
-
605
- it "should correctly fetch an access token" do
606
- @client.client_id = "client-12345"
607
- @client.client_secret = "secret-12345"
608
- @client.code = "00000"
609
- @client.redirect_uri = "https://www.example.com/"
610
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
611
- stub.post "/token" do
612
- build_json_response(
613
- "access_token" => "12345",
614
- "refresh_token" => "54321",
615
- "expires_in" => "3600"
616
- )
617
- end
618
- end
619
- connection = Faraday.new url: "https://www.google.com" do |builder|
620
- builder.adapter :test, stubs
621
- end
622
- @client.fetch_access_token!(
623
- connection: connection
624
- )
625
- expect(@client.access_token).to eq "12345"
626
- expect(@client.refresh_token).to eq "54321"
627
- expect(@client.expires_in).to eq 3600
628
- stubs.verify_stubbed_calls
629
- end
630
-
631
- it "should correctly fetch an access token with a password" do
632
- @client.client_id = "client-12345"
633
- @client.client_secret = "secret-12345"
634
- @client.username = "johndoe"
635
- @client.password = "incognito"
636
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
637
- stub.post "/token" do
638
- build_json_response(
639
- "access_token" => "12345",
640
- "refresh_token" => "54321",
641
- "expires_in" => "3600"
642
- )
643
- end
644
- end
645
- connection = Faraday.new url: "https://www.google.com" do |builder|
646
- builder.adapter :test, stubs
647
- end
648
- @client.fetch_access_token!(
649
- connection: connection
650
- )
651
- expect(@client.access_token).to eq "12345"
652
- expect(@client.refresh_token).to eq "54321"
653
- expect(@client.expires_in).to eq 3600
654
- stubs.verify_stubbed_calls
655
- end
656
-
657
- it "should correctly refresh an access token" do
658
- @client.client_id = "client-12345"
659
- @client.client_secret = "secret-12345"
660
- @client.refresh_token = "54321"
661
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
662
- stub.post "/token" do
663
- build_json_response(
664
- "access_token" => "12345",
665
- "refresh_token" => "54321",
666
- "expires_in" => "3600"
667
- )
668
- end
669
- end
670
- connection = Faraday.new url: "https://www.google.com" do |builder|
671
- builder.adapter :test, stubs
672
- end
673
- @client.fetch_access_token!(
674
- connection: connection
675
- )
676
- expect(@client.access_token).to eq "12345"
677
- expect(@client.refresh_token).to eq "54321"
678
- expect(@client.expires_in).to eq 3600
679
- stubs.verify_stubbed_calls
680
- end
681
-
682
- it "should detect unintential grant type of none" do
683
- @client.client_id = "client-12345"
684
- @client.client_secret = "secret-12345"
685
- @client.redirect_uri = "https://www.example.com/"
686
- expect(lambda do
687
- @client.fetch_access_token!
688
- end).to raise_error(ArgumentError)
689
- end
690
-
691
- it "should correctly fetch protected resources" do
692
- @client.client_id = "client-12345"
693
- @client.client_secret = "secret-12345"
694
- @client.access_token = "12345"
695
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
696
- stub.get "/oauth2/v1/userinfo?alt=json" do
697
- [200, {}, <<~JSON]
698
- {
699
- "id": "116452824309856782163",
700
- "name": "Bob Aman",
701
- "given_name": "Bob",
702
- "family_name": "Aman",
703
- "link": "https://plus.google.com/116452824309856782163"
704
- }
705
- JSON
706
- end
707
- end
708
- connection = Faraday.new url: "https://www.googleapis.com" do |builder|
709
- builder.adapter :test, stubs
710
- end
711
- response = @client.fetch_protected_resource(
712
- connection: connection,
713
- uri: "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"
714
- )
715
- expect(response.status).to eq 200
716
- expect(response.body).to eq <<~JSON
717
- {
718
- "id": "116452824309856782163",
719
- "name": "Bob Aman",
720
- "given_name": "Bob",
721
- "family_name": "Aman",
722
- "link": "https://plus.google.com/116452824309856782163"
723
- }
724
- JSON
725
- stubs.verify_stubbed_calls
726
- end
727
-
728
- it "should correctly send the realm in the Authorization header" do
729
- @client.client_id = "client-12345"
730
- @client.client_secret = "secret-12345"
731
- @client.access_token = "12345"
732
- connection = Faraday.new url: "https://www.googleapis.com" do |builder|
733
- builder.adapter :test
734
- end
735
- request = @client.generate_authenticated_request(
736
- connection: connection,
737
- realm: "Example",
738
- request: conn.build_request(:get) do |req|
739
- req.url "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"
740
- end
741
- )
742
- expect(request.headers["Authorization"]).to eq 'Bearer 12345, realm="Example"'
743
- end
744
-
745
- it "should correctly send the realm in the Authorization header" do
746
- @client.client_id = "client-12345"
747
- @client.client_secret = "secret-12345"
748
- @client.access_token = "12345"
749
- connection = Faraday.new url: "https://www.googleapis.com" do |builder|
750
- builder.adapter :test
751
- end
752
- request = @client.generate_authenticated_request(
753
- connection: connection,
754
- realm: "Example",
755
- request: [
756
- "GET",
757
- "https://www.googleapis.com/oauth2/v1/userinfo?alt=json",
758
- {},
759
- [""]
760
- ]
761
- )
762
- expect(request.headers["Authorization"]).to eq 'Bearer 12345, realm="Example"'
763
- end
764
-
765
- it "should not raise an error if a request is " \
766
- "provided without a connection" do
767
- @client.client_id = "client-12345"
768
- @client.client_secret = "secret-12345"
769
- @client.access_token = "12345"
770
- request = @client.generate_authenticated_request(
771
- realm: "Example",
772
- request: conn.build_request(:get) do |req|
773
- req.url "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"
774
- end
775
- )
776
- end
777
-
778
- it "should raise an error if not enough information " \
779
- "is supplied to create a request" do
780
- @client.client_id = "client-12345"
781
- @client.client_secret = "secret-12345"
782
- @client.access_token = "12345"
783
- expect(lambda do
784
- @client.generate_authenticated_request(
785
- realm: "Example",
786
- method: "POST"
787
- )
788
- end).to raise_error(ArgumentError)
789
- end
790
-
791
- it "should raise an error if the client does not have an access token" do
792
- @client.client_id = "client-12345"
793
- @client.client_secret = "secret-12345"
794
- expect(lambda do
795
- @client.fetch_protected_resource
796
- end).to raise_error(ArgumentError)
797
- end
798
-
799
- it "should not raise an error if the API server gives an error status" do
800
- @client.client_id = "client-12345"
801
- @client.client_secret = "secret-12345"
802
- @client.access_token = "12345"
803
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
804
- stub.get "/oauth2/v1/userinfo?alt=json" do
805
- [509, {}, "Rate limit hit or something."]
806
- end
807
- end
808
- connection = Faraday.new url: "https://www.googleapis.com" do |builder|
809
- builder.adapter :test, stubs
810
- end
811
- response = @client.fetch_protected_resource(
812
- connection: connection,
813
- uri: "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"
814
- )
815
- expect(response.status).to eq 509
816
- expect(response.body).to eq "Rate limit hit or something."
817
- stubs.verify_stubbed_calls
818
- end
819
-
820
- it "should only raise an error if the API server " \
821
- "gives an authorization failed status" do
822
- @client.client_id = "client-12345"
823
- @client.client_secret = "secret-12345"
824
- @client.access_token = "12345"
825
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
826
- stub.get "/oauth2/v1/userinfo?alt=json" do
827
- [401, {}, "User authorization failed or something."]
828
- end
829
- end
830
- expect(lambda do
831
- connection = Faraday.new(
832
- url: "https://www.googleapis.com"
833
- ) do |builder|
834
- builder.adapter :test, stubs
835
- end
836
- @client.fetch_protected_resource(
837
- connection: connection,
838
- uri: "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"
839
- )
840
- end).to raise_error(Signet::AuthorizationError)
841
- stubs.verify_stubbed_calls
842
- end
843
-
844
- it "should correctly handle an ID token" do
845
- @client.client_id = "client-12345"
846
- @client.client_secret = "secret-12345"
847
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
848
- stub.post "/token" do
849
- build_json_response(
850
- "access_token" => "12345",
851
- "refresh_token" => "54321",
852
- "expires_in" => "3600",
853
- "id_token" => (
854
- "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD" \
855
- "lKN244VjBOMnZjdzZlTWlqZyIsImF1ZCI6ImNsaWVudC0xMjM0NSIsImlkIjoiM" \
856
- "TIzNDUiLCJpYXQiOjEzMjA2NzA5NzgsImV4cCI6MTMyMDY3NDg3OCwiY2lkIjoi" \
857
- "Y2xpZW50LTEyMzQ1IiwiaXNzIjoiZXhhbXBsZS5jb20ifQ.tsF3srlBaAh6pV3U" \
858
- "wfRrHSA3-jwnvOw6MMsQ6sO4kjc"
859
- )
860
- )
861
- end
862
- end
863
- connection = Faraday.new url: "https://www.google.com" do |builder|
864
- builder.adapter :test, stubs
865
- end
866
- @client.fetch_access_token!(
867
- connection: connection
868
- )
869
- expect(@client.access_token).to eq "12345"
870
- expect(@client.refresh_token).to eq "54321"
871
- expect(@client.decoded_id_token(nil, verify_expiration: false)).to eq ({
872
- "token_hash" => "tghD9J7n8V0N2vcw6eMijg",
873
- "id" => "12345",
874
- "aud" => "client-12345",
875
- "iat" => 1_320_670_978,
876
- "exp" => 1_320_674_878,
877
- "cid" => "client-12345",
878
- "iss" => "example.com"
879
- })
880
- expect(@client.expires_in).to eq 3600
881
- stubs.verify_stubbed_calls
882
- end
883
-
884
- it "should correctly handle an ID token with `aud` array" do
885
- @client.client_id = "client-12345"
886
- @client.client_secret = "secret-12345"
887
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
888
- stub.post "/token" do
889
- build_json_response(
890
- "access_token" => "12345",
891
- "refresh_token" => "54321",
892
- "expires_in" => "3600",
893
- "id_token" => (
894
- "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD" \
895
- "lKN244VjBOMnZjdzZlTWlqZyIsImF1ZCI6WyJjbGllbnQtMTIzNDUiXSwiaWQiO" \
896
- "iIxMjM0NSIsImlhdCI6MTMyMDY3MDk3OCwiZXhwIjoxMzIwNjc0ODc4LCJjaWQi" \
897
- "OiJjbGllbnQtMTIzNDUiLCJpc3MiOiJleGFtcGxlLmNvbSJ9.rSaY-M9YlB4pcU" \
898
- "uNf21FeEtOM9pBGr_a7xe9fZrpWWU"
899
- )
900
- )
901
- end
902
- end
903
- connection = Faraday.new url: "https://www.google.com" do |builder|
904
- builder.adapter :test, stubs
905
- end
906
- @client.fetch_access_token!(
907
- connection: connection
908
- )
909
- expect(@client.access_token).to eq "12345"
910
- expect(@client.refresh_token).to eq "54321"
911
- expect(@client.decoded_id_token(nil, verify_expiration: false)).to eq ({
912
- "token_hash" => "tghD9J7n8V0N2vcw6eMijg",
913
- "id" => "12345",
914
- "aud" => ["client-12345"],
915
- "iat" => 1_320_670_978,
916
- "exp" => 1_320_674_878,
917
- "cid" => "client-12345",
918
- "iss" => "example.com"
919
- })
920
- expect(@client.expires_in).to eq 3600
921
- stubs.verify_stubbed_calls
922
- end
923
-
924
- it "should raise an error decoding an ID token if " \
925
- "audience does not match client ID" do
926
- @client.client_id = "client-54321"
927
- @client.client_secret = "secret-12345"
928
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
929
- stub.post "/token" do
930
- build_json_response(
931
- "access_token" => "12345",
932
- "refresh_token" => "54321",
933
- "expires_in" => "3600",
934
- "id_token" => (
935
- "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD" \
936
- "lKN244VjBOMnZjdzZlTWlqZyIsImF1ZCI6ImNsaWVudC0xMjM0NSIsImlkIjoiM" \
937
- "TIzNDUiLCJpYXQiOjEzMjA2NzA5NzgsImV4cCI6MTMyMDY3NDg3OCwiY2lkIjoi" \
938
- "Y2xpZW50LTEyMzQ1IiwiaXNzIjoiZXhhbXBsZS5jb20ifQ.tsF3srlBaAh6pV3U" \
939
- "wfRrHSA3-jwnvOw6MMsQ6sO4kjc"
940
- )
941
- )
942
- end
943
- end
944
- connection = Faraday.new url: "https://www.google.com" do |builder|
945
- builder.adapter :test, stubs
946
- end
947
- @client.fetch_access_token!(
948
- connection: connection
949
- )
950
- expect(@client.access_token).to eq "12345"
951
- expect(@client.refresh_token).to eq "54321"
952
- expect(@client.expires_in).to eq 3600
953
- expect(lambda do
954
- @client.decoded_id_token nil, verify_expiration: false
955
- end).to raise_error(Signet::UnsafeOperationError)
956
- stubs.verify_stubbed_calls
957
- end
958
-
959
- it "should raise an error decoding an ID token if " \
960
- "audience is missing" do
961
- @client.client_id = "client-12345"
962
- @client.client_secret = "secret-12345"
963
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
964
- stub.post "/token" do
965
- build_json_response(
966
- "access_token" => "12345",
967
- "refresh_token" => "54321",
968
- "expires_in" => "3600",
969
- "id_token" => (
970
- "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD" \
971
- "lKN244VjBOMnZjdzZlTWlqZyIsImlkIjoiMTIzNDUiLCJpYXQiOjEzMjA2NzA5N" \
972
- "zgsImV4cCI6MTMyMDY3NDg3OCwiY2lkIjoiY2xpZW50LTEyMzQ1IiwiaXNzIjoi" \
973
- "ZXhhbXBsZS5jb20ifQ.7qj85CKbQyVdDe5y2ScdJAZNkEeKMPW9LIonLxG1vu8"
974
- )
975
- )
976
- end
977
- end
978
- connection = Faraday.new url: "https://www.google.com" do |builder|
979
- builder.adapter :test, stubs
980
- end
981
- @client.fetch_access_token!(
982
- connection: connection
983
- )
984
- expect(@client.access_token).to eq "12345"
985
- expect(@client.refresh_token).to eq "54321"
986
- expect(@client.expires_in).to eq 3600
987
- expect(lambda do
988
- @client.decoded_id_token nil, verify_expiration: false
989
- end).to raise_error(Signet::UnsafeOperationError)
990
- stubs.verify_stubbed_calls
991
- end
992
-
993
- it "should raise an error if the id token cannot be verified" do
994
- pending "Need to set test data"
995
- @client.client_id = "client-12345"
996
- @client.client_secret = "secret-12345"
997
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
998
- stub.post "/token" do
999
- build_json_response(
1000
- "access_token" => "12345",
1001
- "refresh_token" => "54321",
1002
- "expires_in" => "3600",
1003
- "id_token" => (
1004
- "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiY" \
1005
- "XVkIjoiMTA2MDM1Nzg5MTY4OC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSI" \
1006
- "sImNpZCI6IjEwNjAzNTc4OTE2ODguYXBwcy5nb29nbGV1c2VyY29udGVudC5jb" \
1007
- "20iLCJpZCI6IjExNjQ1MjgyNDMwOTg1Njc4MjE2MyIsInRva2VuX2hhc2giOiJ" \
1008
- "0Z2hEOUo4bjhWME4ydmN3NmVNaWpnIiwiaWF0IjoxMzIwNjcwOTc4LCJleHAiO" \
1009
- "jEzMjA2NzQ4Nzh9.D8x_wirkxDElqKdJBcsIws3Ogesk38okz6MN7zqC7nEAA7" \
1010
- "wcy1PxsROY1fmBvXSer0IQesAqOW-rPOCNReSn-eY8d53ph1x2HAF-AzEi3GOl" \
1011
- "6hFycH8wj7Su6JqqyEbIVLxE7q7DkAZGaMPkxbTHs1EhSd5_oaKQ6O4xO3ZnnT4"
1012
- )
1013
- )
1014
- end
1015
- end
1016
- connection = Faraday.new url: "https://www.google.com" do |builder|
1017
- builder.adapter :test, stubs
1018
- end
1019
- @client.fetch_access_token!(
1020
- connection: connection
1021
- )
1022
- expect(@client.access_token).to eq "12345"
1023
- expect(@client.refresh_token).to eq "54321"
1024
- expect(@client.expires_in).to eq 3600
1025
- expect(lambda do
1026
- pubkey = OpenSSL::PKey::RSA.new <<~PUBKEY
1027
- -----BEGIN PUBLIC KEY-----
1028
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCaY7425h964bjaoLeUm
1029
- SlZ8sK7VtVk9zHbGmZh2ygGYwfuUf2bmMye2Ofv99yDE/rd4loVIAcu7RVvDRgHq
1030
- 3/CZTnIrSvHsiJQsHBNa3d+F1ihPfzURzf1M5k7CFReBj2SBXhDXd57oRfBQj12w
1031
- CVhhwP6kGTAWuoppbIIIBfNF2lE/Nvm7lVVYQqL9xOrP/AQ4xRbpQlB8Ll9sO9Or
1032
- SvbWhCDa/LMOWxHdmrcJi6XoSg1vnOyCoKbyAoauTt/XqdkHbkDdQ6HFbJieu9il
1033
- LDZZNliPhfENuKeC2MCGVXTEu8Cqhy1w6e4axavLlXoYf4laJIZ/e7au8SqDbY0B
1034
- xwIDAQAB
1035
- -----END PUBLIC KEY-----
1036
- PUBKEY
1037
- @client.decoded_id_token pubkey
1038
- end).to raise_error(JWT::ExpiredSignature)
1039
- stubs.verify_stubbed_calls
1040
- end
1041
- end
1042
-
1043
- describe Signet::OAuth2::Client, "authorization_uri" do
1044
- before do
1045
- @client = Signet::OAuth2::Client.new(
1046
- client_id: "s6BhdRkqt3",
1047
- redirect_uri: "https://example.client.com/callback",
1048
- authorization_uri: "https://example.com/authorize"
1049
- )
1050
- end
1051
-
1052
- it "should set access_type to offline by default" do
1053
- expect(@client.authorization_uri.query_values["access_type"]).to eq "offline"
1054
- end
1055
-
1056
- it "should set response_type to code by default" do
1057
- expect(@client.authorization_uri.query_values["response_type"]).to eq "code"
1058
- end
1059
-
1060
- it "should raise an error when setting both prompt and approval_prompt" do
1061
- expect(lambda do
1062
- @client.authorization_uri approval_prompt: "force", prompt: "consent"
1063
- end).to raise_error(ArgumentError)
1064
- end
1065
- end
1066
-
1067
- describe Signet::OAuth2::Client, "configured with custom parameters" do
1068
- before do
1069
- @client = Signet::OAuth2::Client.new(
1070
- client_id: "s6BhdRkqt3",
1071
- redirect_uri: "https://example.client.com/callback",
1072
- authorization_uri: "https://example.com/authorize",
1073
- token_credential_uri: "https://example.com/token",
1074
- additional_parameters: { "type" => "web_server" }
1075
- )
1076
- end
1077
-
1078
- # Normalizing to symbols - good test case example here for changes to normalized input.
1079
- # Also tests Addressable's output.
1080
- # Note: The only changes made here are to testing the **INTERNAL** representation of options.
1081
- it "should allow custom parameters to be set on init" do
1082
- expect(@client.additional_parameters).to eq({ type: "web_server" })
1083
- end
1084
-
1085
- it "should allow custom parameters to be updated" do
1086
- @client.update! additional_parameters: { type: "new_type" }
1087
- expect(@client.additional_parameters).to eq ({ type: "new_type" })
1088
- end
1089
-
1090
- it "should use custom parameters when generating authorization_uri" do
1091
- expect(@client.authorization_uri.query_values).to eq ({
1092
- "access_type" => "offline",
1093
- "client_id" => "s6BhdRkqt3",
1094
- "redirect_uri" => "https://example.client.com/callback",
1095
- "response_type" => "code",
1096
- "type" => "web_server"
1097
- })
1098
- end
1099
-
1100
- it "should merge new authorization_uri custom parameters" do
1101
- expect(@client.authorization_uri(additional_parameters: { "type" => "new_type", "new_param" => "new_val" }).query_values).to eql({ "access_type" => "offline", "client_id" => "s6BhdRkqt3", "new_param" => "new_val", "response_type" => "code", "redirect_uri" => "https://example.client.com/callback", "type" => "new_type" })
1102
- end
1103
-
1104
- it "should merge new generate_access_token_request custom parameters" do
1105
- @client.update! code: "12345"
1106
- params = @client.generate_access_token_request additional_parameters: { "type" => "new_type", "new_param" => "new_val" }
1107
- expect(params).to include("type" => "new_type")
1108
- expect(params).to include("new_param" => "new_val")
1109
- end
1110
- end
1111
-
1112
- describe Signet::OAuth2::Client, "configured with custom parameters" do
1113
- before do
1114
- @client = Signet::OAuth2::Client.new(
1115
- "client_id" => "s6BhdRkqt3",
1116
- "redirect_uri" => "https://example.client.com/callback",
1117
- "authorization_uri" => "https://example.com/authorize",
1118
- "token_credential_uri" => "https://example.com/token",
1119
- "additional_parameters" => { "type" => "web_server" }
1120
- )
1121
- end
1122
-
1123
- # Normalizing to symbols - good test case example here for changes to normalized input.
1124
- # Also tests Addressable's output.
1125
- # Note: The only changes made here are to testing the **INTERNAL** representation of options.
1126
- it "should allow custom parameters to be set on init" do
1127
- expect(@client.additional_parameters).to eq ({ type: "web_server" })
1128
- end
1129
-
1130
- it "should allow custom parameters to be updated" do
1131
- @client.update! additional_parameters: { "type" => "new_type" }
1132
- expect(@client.additional_parameters).to eql ({ type: "new_type" })
1133
- end
1134
-
1135
- it "should use custom parameters when generating authorization_uri" do
1136
- expect(@client.authorization_uri.query_values).to eq ({ "access_type" => "offline", "client_id" => "s6BhdRkqt3", "redirect_uri" => "https://example.client.com/callback", "response_type" => "code", "type" => "web_server" })
1137
- end
1138
-
1139
- it "should have the correct authorization_uri" do
1140
- expect(@client.authorization_uri.host).to eq "example.com"
1141
- expect(@client.authorization_uri.path).to eq "/authorize"
1142
- end
1143
-
1144
- it "should merge new authorization_uri custom parameters" do
1145
- expect(@client.authorization_uri(additional_parameters: { "type" => "new_type", "new_param" => "new_val" }).query_values).to eq ({ "access_type" => "offline", "client_id" => "s6BhdRkqt3", "new_param" => "new_val", "response_type" => "code", "redirect_uri" => "https://example.client.com/callback", "type" => "new_type" })
1146
- end
1147
-
1148
- it "should not have access_type parameter in authorization_uri when we set it to nil in client" do
1149
- @client.update! access_type: nil
1150
- expect(@client.authorization_uri.query_values).to eq ({ "client_id" => "s6BhdRkqt3", "response_type" => "code", "redirect_uri" => "https://example.client.com/callback" })
1151
- end
1152
-
1153
- it "should use new access_type parameter as default for authorization_uri" do
1154
- @client.update! access_type: :online
1155
- expect(@client.authorization_uri.query_values).to eq ({ "access_type" => "online", "client_id" => "s6BhdRkqt3", "response_type" => "code", "redirect_uri" => "https://example.client.com/callback" })
1156
- end
1157
-
1158
- it "should merge new generate_access_token_request custom parameters" do
1159
- @client.update! code: "12345"
1160
- params = @client.generate_access_token_request additional_parameters: { "type" => "new_type", "new_param" => "new_val" }
1161
- expect(params).to include("type" => "new_type")
1162
- expect(params).to include("new_param" => "new_val")
1163
- end
1164
- end
1165
-
1166
- describe Signet::OAuth2::Client, "configured with custom parameters a la JSON.load(credentials_file)" do
1167
- before do
1168
- @client = Signet::OAuth2::Client.new(
1169
- "client_id" => "s6BhdRkqt3",
1170
- "redirect_uri" => "https://example.client.com/callback",
1171
- "authorization_uri" => { "scheme" => "https", "user" => nil, "password" => nil, "host" => "accounts.google.com", "port" => nil, "path" => "/o/oauth2/auth", "query" => nil, "fragment" => nil },
1172
- "token_credential_uri" => "https://example.com/token",
1173
- "additional_parameters" => { "type" => "web_server" }
1174
- )
1175
- end
1176
-
1177
- it "should allow custom parameters to be set on init" do
1178
- expect(@client.additional_parameters).to eq ({ type: "web_server" })
1179
- end
1180
-
1181
- it "should allow custom parameters to be updated" do
1182
- @client.update! additional_parameters: { "type" => "new_type" }
1183
- expect(@client.additional_parameters).to eql ({ type: "new_type" })
1184
- end
1185
-
1186
- it "should have correct authorization_uri hash options" do
1187
- expect(@client.authorization_uri.host).to eq "accounts.google.com"
1188
- expect(@client.authorization_uri.path).to eq "/o/oauth2/auth"
1189
- end
1190
-
1191
- it "should use custom parameters when generating authorization_uri" do
1192
- expect(@client.authorization_uri.query_values).to eq ({ "access_type" => "offline", "client_id" => "s6BhdRkqt3", "redirect_uri" => "https://example.client.com/callback", "response_type" => "code", "type" => "web_server" })
1193
- end
1194
-
1195
- # , "path" => "/o/oauth2/oauth", "host" => "accounts.google.com"
1196
-
1197
- it "should merge new authorization_uri custom parameters" do
1198
- expect(@client.authorization_uri(additional_parameters: { "type" => "new_type", "new_param" => "new_val" }).query_values).to eq ({
1199
- "access_type" => "offline",
1200
- "client_id" => "s6BhdRkqt3",
1201
- "new_param" => "new_val",
1202
- "response_type" => "code",
1203
- "redirect_uri" => "https://example.client.com/callback",
1204
- "type" => "new_type"
1205
- })
1206
- end
1207
-
1208
- it "should merge new generate_access_token_request custom parameters" do
1209
- @client.update! code: "12345"
1210
- params = @client.generate_access_token_request additional_parameters: { "type" => "new_type", "new_param" => "new_val" }
1211
- expect(params).to include("type" => "new_type")
1212
- expect(params).to include("new_param" => "new_val")
1213
- end
1214
- end
1215
-
1216
- describe Signet::OAuth2::Client, "configured for id tokens" do
1217
- before do
1218
- @key = OpenSSL::PKey::RSA.new 2048
1219
- @client = Signet::OAuth2::Client.new(
1220
- token_credential_uri: "https://oauth2.googleapis.com/token",
1221
- target_audience: "https://api.example.com",
1222
- issuer: "app@example.com",
1223
- audience: "https://hello.googleapis.com",
1224
- signing_key: @key
1225
- )
1226
- end
1227
-
1228
- it "should set target_audience" do
1229
- expect(@client.target_audience).to eq "https://api.example.com"
1230
- end
1231
-
1232
- it "should send a valid id token request" do
1233
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
1234
- stub.post "/token" do |env|
1235
- params = Addressable::URI.form_unencode env[:body]
1236
- claim, header = JWT.decode params.assoc("assertion").last, @key.public_key, true, algorithm: "RS256"
1237
- expect(params.assoc("grant_type")).to eq ["grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"]
1238
- expect(claim["target_audience"]).to eq "https://api.example.com"
1239
- expect(claim["iss"]).to eq "app@example.com"
1240
- expect(claim["aud"]).to eq "https://hello.googleapis.com"
1241
- build_json_response(
1242
- "id_token" => "12345id",
1243
- "refresh_token" => "54321refresh",
1244
- "expires_in" => "3600"
1245
- )
1246
- end
1247
- end
1248
- connection = Faraday.new url: "https://www.google.com" do |builder|
1249
- builder.adapter :test, stubs
1250
- end
1251
- @client.fetch_access_token! connection: connection
1252
- expect(@client.id_token).to eq "12345id"
1253
- end
1254
- end