googleauth 0.17.0 → 1.1.1

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.md +23 -19
  4. data/README.md +24 -2
  5. data/lib/googleauth/application_default.rb +10 -25
  6. data/lib/googleauth/client_id.rb +10 -25
  7. data/lib/googleauth/compute_engine.rb +10 -25
  8. data/lib/googleauth/credentials.rb +11 -26
  9. data/lib/googleauth/credentials_loader.rb +11 -26
  10. data/lib/googleauth/default_credentials.rb +10 -25
  11. data/lib/googleauth/iam.rb +10 -25
  12. data/lib/googleauth/id_tokens/errors.rb +9 -23
  13. data/lib/googleauth/id_tokens/key_sources.rb +10 -23
  14. data/lib/googleauth/id_tokens/verifier.rb +9 -23
  15. data/lib/googleauth/id_tokens.rb +9 -23
  16. data/lib/googleauth/json_key_reader.rb +10 -25
  17. data/lib/googleauth/scope_util.rb +10 -25
  18. data/lib/googleauth/service_account.rb +10 -25
  19. data/lib/googleauth/signet.rb +21 -27
  20. data/lib/googleauth/stores/file_token_store.rb +10 -25
  21. data/lib/googleauth/stores/redis_token_store.rb +10 -25
  22. data/lib/googleauth/token_store.rb +10 -25
  23. data/lib/googleauth/user_authorizer.rb +10 -25
  24. data/lib/googleauth/user_refresh.rb +15 -27
  25. data/lib/googleauth/version.rb +11 -26
  26. data/lib/googleauth/web_user_authorizer.rb +10 -25
  27. data/lib/googleauth.rb +10 -25
  28. metadata +22 -90
  29. data/.github/CODEOWNERS +0 -7
  30. data/.github/CONTRIBUTING.md +0 -74
  31. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -36
  32. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -21
  33. data/.github/ISSUE_TEMPLATE/support_request.md +0 -7
  34. data/.github/renovate.json +0 -6
  35. data/.github/sync-repo-settings.yaml +0 -18
  36. data/.github/workflows/ci.yml +0 -55
  37. data/.github/workflows/release-please.yml +0 -39
  38. data/.gitignore +0 -39
  39. data/.kokoro/populate-secrets.sh +0 -76
  40. data/.kokoro/release.cfg +0 -52
  41. data/.kokoro/release.sh +0 -18
  42. data/.kokoro/trampoline_v2.sh +0 -489
  43. data/.repo-metadata.json +0 -5
  44. data/.rspec +0 -2
  45. data/.rubocop.yml +0 -17
  46. data/.toys/.toys.rb +0 -45
  47. data/.toys/ci.rb +0 -43
  48. data/.toys/kokoro/.toys.rb +0 -66
  49. data/.toys/kokoro/publish-docs.rb +0 -67
  50. data/.toys/kokoro/publish-gem.rb +0 -53
  51. data/.toys/linkinator.rb +0 -43
  52. data/.trampolinerc +0 -48
  53. data/Gemfile +0 -25
  54. data/googleauth.gemspec +0 -39
  55. data/integration/helper.rb +0 -31
  56. data/integration/id_tokens/key_source_test.rb +0 -74
  57. data/spec/googleauth/apply_auth_examples.rb +0 -171
  58. data/spec/googleauth/client_id_spec.rb +0 -160
  59. data/spec/googleauth/compute_engine_spec.rb +0 -178
  60. data/spec/googleauth/credentials_spec.rb +0 -600
  61. data/spec/googleauth/get_application_default_spec.rb +0 -286
  62. data/spec/googleauth/iam_spec.rb +0 -80
  63. data/spec/googleauth/scope_util_spec.rb +0 -77
  64. data/spec/googleauth/service_account_spec.rb +0 -511
  65. data/spec/googleauth/signet_spec.rb +0 -142
  66. data/spec/googleauth/stores/file_token_store_spec.rb +0 -57
  67. data/spec/googleauth/stores/redis_token_store_spec.rb +0 -50
  68. data/spec/googleauth/stores/store_examples.rb +0 -58
  69. data/spec/googleauth/user_authorizer_spec.rb +0 -343
  70. data/spec/googleauth/user_refresh_spec.rb +0 -359
  71. data/spec/googleauth/web_user_authorizer_spec.rb +0 -172
  72. data/spec/spec_helper.rb +0 -92
  73. data/test/helper.rb +0 -33
  74. data/test/id_tokens/key_sources_test.rb +0 -240
  75. data/test/id_tokens/verifier_test.rb +0 -269
@@ -1,511 +0,0 @@
1
- # Copyright 2015, Google Inc.
2
- # All rights reserved.
3
- #
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are
6
- # met:
7
- #
8
- # * Redistributions of source code must retain the above copyright
9
- # notice, this list of conditions and the following disclaimer.
10
- # * Redistributions in binary form must reproduce the above
11
- # copyright notice, this list of conditions and the following disclaimer
12
- # in the documentation and/or other materials provided with the
13
- # distribution.
14
- # * Neither the name of Google Inc. nor the names of its
15
- # contributors may be used to endorse or promote products derived from
16
- # this software without specific prior written permission.
17
- #
18
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- spec_dir = File.expand_path File.join(File.dirname(__FILE__))
31
- $LOAD_PATH.unshift spec_dir
32
- $LOAD_PATH.uniq!
33
-
34
- require "apply_auth_examples"
35
- require "fakefs/safe"
36
- require "fileutils"
37
- require "googleauth/service_account"
38
- require "jwt"
39
- require "multi_json"
40
- require "openssl"
41
- require "spec_helper"
42
- require "tmpdir"
43
- require "os"
44
-
45
- include Google::Auth::CredentialsLoader
46
-
47
- shared_examples "jwt header auth" do |aud="https://www.googleapis.com/myservice"|
48
- context "when jwt_aud_uri is present" do
49
- let(:test_uri) { aud }
50
- let(:test_scope) { "scope/1 scope/2" }
51
- let(:auth_prefix) { "Bearer " }
52
- let(:auth_key) { ServiceAccountJwtHeaderCredentials::AUTH_METADATA_KEY }
53
- let(:jwt_uri_key) { ServiceAccountJwtHeaderCredentials::JWT_AUD_URI_KEY }
54
-
55
- def expect_is_encoded_jwt hdr
56
- expect(hdr).to_not be_nil
57
- expect(hdr.start_with?(auth_prefix)).to be true
58
- authorization = hdr[auth_prefix.length..-1]
59
- payload, = JWT.decode authorization, @key.public_key, true, algorithm: "RS256"
60
-
61
- expect(payload["aud"]).to eq(test_uri) if not test_uri.nil?
62
- expect(payload["scope"]).to eq(test_scope) if test_uri.nil?
63
- expect(payload["iss"]).to eq(client_email)
64
- end
65
-
66
- describe "#apply!" do
67
- it "should update the target hash with a jwt token" do
68
- md = { foo: "bar" }
69
- md[jwt_uri_key] = test_uri if test_uri
70
- @client.apply! md
71
- auth_header = md[auth_key]
72
- expect_is_encoded_jwt auth_header
73
- expect(md[jwt_uri_key]).to be_nil
74
- end
75
- end
76
-
77
- describe "updater_proc" do
78
- it "should provide a proc that updates a hash with a jwt token" do
79
- md = { foo: "bar" }
80
- md[jwt_uri_key] = test_uri if test_uri
81
- the_proc = @client.updater_proc
82
- got = the_proc.call md
83
- auth_header = got[auth_key]
84
- expect_is_encoded_jwt auth_header
85
- expect(got[jwt_uri_key]).to be_nil
86
- expect(md[jwt_uri_key]).to_not be_nil if test_uri
87
- end
88
- end
89
-
90
- describe "#apply" do
91
- it "should not update the original hash with a jwt token" do
92
- md = { foo: "bar" }
93
- md[jwt_uri_key] = test_uri if test_uri
94
- the_proc = @client.updater_proc
95
- got = the_proc.call md
96
- auth_header = md[auth_key]
97
- expect(auth_header).to be_nil
98
- expect(got[jwt_uri_key]).to be_nil
99
- expect(md[jwt_uri_key]).to_not be_nil if test_uri
100
- end
101
-
102
- it "should add a jwt token to the returned hash" do
103
- md = { foo: "bar" }
104
- md[jwt_uri_key] = test_uri if test_uri
105
- got = @client.apply md
106
- auth_header = got[auth_key]
107
- expect_is_encoded_jwt auth_header
108
- end
109
- end
110
- end
111
- end
112
-
113
-
114
- describe Google::Auth::ServiceAccountCredentials do
115
- ServiceAccountCredentials = Google::Auth::ServiceAccountCredentials
116
- let(:client_email) { "app@developer.gserviceaccount.com" }
117
- let :cred_json do
118
- {
119
- private_key_id: "a_private_key_id",
120
- private_key: @key.to_pem,
121
- client_email: client_email,
122
- client_id: "app.apps.googleusercontent.com",
123
- type: "service_account",
124
- project_id: "a_project_id",
125
- quota_project_id: "b_project_id"
126
- }
127
- end
128
-
129
- before :example do
130
- @key = OpenSSL::PKey::RSA.new 2048
131
- @client = ServiceAccountCredentials.make_creds(
132
- json_key_io: StringIO.new(cred_json_text),
133
- scope: "https://www.googleapis.com/auth/userinfo.profile"
134
- )
135
- @id_client = ServiceAccountCredentials.make_creds(
136
- json_key_io: StringIO.new(cred_json_text),
137
- target_audience: "https://pubsub.googleapis.com/"
138
- )
139
- end
140
-
141
- def make_auth_stubs opts
142
- body_fields = { "token_type" => "Bearer", "expires_in" => 3600 }
143
- body_fields["access_token"] = opts[:access_token] if opts[:access_token]
144
- body_fields["id_token"] = opts[:id_token] if opts[:id_token]
145
- body = MultiJson.dump body_fields
146
- blk = proc do |request|
147
- params = Addressable::URI.form_unencode request.body
148
- claim, _header = JWT.decode(params.assoc("assertion").last,
149
- @key.public_key, true,
150
- algorithm: "RS256")
151
- !opts[:id_token] || claim["target_audience"] == "https://pubsub.googleapis.com/"
152
- end
153
- stub_request(:post, "https://www.googleapis.com/oauth2/v4/token")
154
- .with(body: hash_including(
155
- "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer"
156
- ), &blk)
157
- .to_return(body: body,
158
- status: 200,
159
- headers: { "Content-Type" => "application/json" })
160
- end
161
-
162
- def cred_json_text
163
- MultiJson.dump cred_json
164
- end
165
-
166
- it_behaves_like "apply/apply! are OK"
167
-
168
- context "when scope is nil" do
169
- before :example do
170
- @client.scope = nil
171
- end
172
-
173
- it_behaves_like "jwt header auth"
174
- end
175
-
176
- context "when enable_self_signed_jwt is set with aud" do
177
- before :example do
178
- @client.scope = nil
179
- @client.instance_variable_set(:@enable_self_signed_jwt, true)
180
- end
181
-
182
- it_behaves_like "jwt header auth"
183
- end
184
-
185
- context "when enable_self_signed_jwt is set with scope" do
186
- before :example do
187
- @client.scope = ['scope/1', 'scope/2']
188
- @client.instance_variable_set(:@enable_self_signed_jwt, true)
189
- end
190
-
191
- it_behaves_like "jwt header auth", nil
192
- end
193
-
194
- describe "#from_env" do
195
- before :example do
196
- @var_name = ENV_VAR
197
- @credential_vars = [
198
- ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
199
- ]
200
- @original_env_vals = {}
201
- @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
202
- ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
203
-
204
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
205
- @clz = ServiceAccountCredentials
206
- end
207
-
208
- after :example do
209
- @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
210
- end
211
-
212
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
213
- ENV.delete @var_name unless ENV[@var_name].nil?
214
- expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
215
- end
216
-
217
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
218
- ENV[@var_name] = ""
219
- expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
220
- end
221
-
222
- it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
223
- ENV.delete @var_name unless ENV[@var_name].nil?
224
- expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
225
- Dir.mktmpdir do |dir|
226
- key_path = File.join dir, "does-not-exist"
227
- ENV[@var_name] = key_path
228
- expect { @clz.from_env @scope }.to raise_error RuntimeError
229
- end
230
- end
231
-
232
- it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
233
- Dir.mktmpdir do |dir|
234
- key_path = File.join dir, "my_cert_file"
235
- FileUtils.mkdir_p File.dirname(key_path)
236
- File.write key_path, cred_json_text
237
- ENV[@var_name] = key_path
238
- expect(@clz.from_env(@scope)).to_not be_nil
239
- end
240
- end
241
-
242
- it "succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are"\
243
- " valid" do
244
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
245
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
246
- expect(@clz.from_env(@scope)).to_not be_nil
247
- end
248
-
249
- it "sets project_id when the PROJECT_ID_VAR env var is set" do
250
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
251
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
252
- ENV[PROJECT_ID_VAR] = cred_json[:project_id]
253
- ENV[ENV_VAR] = nil
254
- credentials = @clz.from_env @scope
255
- expect(credentials.project_id).to eq(cred_json[:project_id])
256
- end
257
-
258
- it "succeeds when GOOGLE_PRIVATE_KEY is escaped" do
259
- escaped_key = cred_json[:private_key].gsub "\n", '\n'
260
- ENV[PRIVATE_KEY_VAR] = "\"#{escaped_key}\""
261
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
262
- expect(@clz.from_env(@scope)).to_not be_nil
263
- end
264
-
265
- it "propagates default_connection option" do
266
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
267
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
268
- connection = Faraday.new headers: { "User-Agent" => "hello" }
269
- creds = @clz.from_env @scope, default_connection: connection
270
- expect(creds.build_default_connection).to be connection
271
- end
272
- end
273
-
274
- describe "#from_well_known_path" do
275
- before :example do
276
- @home = ENV["HOME"]
277
- @app_data = ENV["APPDATA"]
278
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
279
- @known_path = WELL_KNOWN_PATH
280
- @clz = ServiceAccountCredentials
281
- end
282
-
283
- after :example do
284
- ENV["HOME"] = @home unless @home == ENV["HOME"]
285
- ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
286
- end
287
-
288
- it "is nil if no file exists" do
289
- ENV["HOME"] = File.dirname __FILE__
290
- expect(ServiceAccountCredentials.from_well_known_path(@scope)).to be_nil
291
- end
292
-
293
- it "successfully loads the file when it is present" do
294
- Dir.mktmpdir do |dir|
295
- key_path = File.join dir, ".config", @known_path
296
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
297
- FileUtils.mkdir_p File.dirname(key_path)
298
- File.write key_path, cred_json_text
299
- ENV["HOME"] = dir
300
- ENV["APPDATA"] = dir
301
- expect(@clz.from_well_known_path(@scope)).to_not be_nil
302
- end
303
- end
304
-
305
- it "successfully sets project_id when file is present" do
306
- Dir.mktmpdir do |dir|
307
- key_path = File.join dir, ".config", @known_path
308
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
309
- FileUtils.mkdir_p File.dirname(key_path)
310
- File.write key_path, cred_json_text
311
- ENV["HOME"] = dir
312
- ENV["APPDATA"] = dir
313
- credentials = @clz.from_well_known_path @scope
314
- expect(credentials.project_id).to eq(cred_json[:project_id])
315
- expect(credentials.quota_project_id).to eq(cred_json[:quota_project_id])
316
- end
317
- end
318
-
319
- it "propagates default_connection option" do
320
- Dir.mktmpdir do |dir|
321
- key_path = File.join dir, ".config", @known_path
322
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
323
- FileUtils.mkdir_p File.dirname(key_path)
324
- File.write key_path, cred_json_text
325
- ENV["HOME"] = dir
326
- ENV["APPDATA"] = dir
327
- connection = Faraday.new headers: { "User-Agent" => "hello" }
328
- creds = @clz.from_well_known_path @scope, default_connection: connection
329
- expect(creds.build_default_connection).to be connection
330
- end
331
- end
332
- end
333
-
334
- describe "#from_system_default_path" do
335
- before :example do
336
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
337
- @program_data = ENV["ProgramData"]
338
- @prefix = OS.windows? ? "/etc/Google/Auth/" : "/etc/google/auth/"
339
- @path = File.join @prefix, CREDENTIALS_FILE_NAME
340
- @clz = ServiceAccountCredentials
341
- end
342
-
343
- after :example do
344
- ENV["ProgramData"] = @program_data
345
- end
346
-
347
- it "is nil if no file exists" do
348
- FakeFS do
349
- expect(ServiceAccountCredentials.from_system_default_path(@scope))
350
- .to be_nil
351
- end
352
- end
353
-
354
- it "successfully loads the file when it is present" do
355
- FakeFS do
356
- ENV["ProgramData"] = "/etc"
357
- FileUtils.mkdir_p File.dirname(@path)
358
- File.write @path, cred_json_text
359
- expect(@clz.from_system_default_path(@scope)).to_not be_nil
360
- File.delete @path
361
- end
362
- end
363
-
364
- it "propagates default_connection option" do
365
- FakeFS do
366
- ENV["ProgramData"] = "/etc"
367
- FileUtils.mkdir_p File.dirname(@path)
368
- File.write @path, cred_json_text
369
- connection = Faraday.new headers: { "User-Agent" => "hello" }
370
- creds = @clz.from_system_default_path @scope, default_connection: connection
371
- expect(creds.build_default_connection).to be connection
372
- File.delete @path
373
- end
374
- end
375
- end
376
- end
377
-
378
- describe Google::Auth::ServiceAccountJwtHeaderCredentials do
379
- ServiceAccountJwtHeaderCredentials =
380
- Google::Auth::ServiceAccountJwtHeaderCredentials
381
-
382
- let(:client_email) { "app@developer.gserviceaccount.com" }
383
- let(:clz) { Google::Auth::ServiceAccountJwtHeaderCredentials }
384
- let :cred_json do
385
- {
386
- private_key_id: "a_private_key_id",
387
- private_key: @key.to_pem,
388
- client_email: client_email,
389
- client_id: "app.apps.googleusercontent.com",
390
- type: "service_account",
391
- project_id: "a_project_id"
392
- }
393
- end
394
-
395
- before :example do
396
- @key = OpenSSL::PKey::RSA.new 2048
397
- @client = clz.make_creds json_key_io: StringIO.new(cred_json_text)
398
- end
399
-
400
- def cred_json_text
401
- MultiJson.dump cred_json
402
- end
403
-
404
- it_behaves_like "jwt header auth"
405
-
406
- describe "#from_env" do
407
- before :example do
408
- @var_name = ENV_VAR
409
- @credential_vars = [
410
- ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
411
- ]
412
- @original_env_vals = {}
413
- @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
414
- ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
415
- end
416
-
417
- after :example do
418
- @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
419
- end
420
-
421
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
422
- ENV.delete @var_name unless ENV[@var_name].nil?
423
- expect(clz.from_env).to be_nil
424
- end
425
-
426
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
427
- ENV[@var_name] = ""
428
- expect(clz.from_env).to be_nil
429
- end
430
-
431
- it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
432
- ENV.delete @var_name unless ENV[@var_name].nil?
433
- expect(clz.from_env).to be_nil
434
- Dir.mktmpdir do |dir|
435
- key_path = File.join dir, "does-not-exist"
436
- ENV[@var_name] = key_path
437
- expect { clz.from_env }.to raise_error RuntimeError
438
- end
439
- end
440
-
441
- it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
442
- Dir.mktmpdir do |dir|
443
- key_path = File.join dir, "my_cert_file"
444
- FileUtils.mkdir_p File.dirname(key_path)
445
- File.write key_path, cred_json_text
446
- ENV[@var_name] = key_path
447
- expect(clz.from_env).to_not be_nil
448
- end
449
- end
450
-
451
- it "succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are"\
452
- " valid" do
453
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
454
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
455
- expect(clz.from_env(@scope)).to_not be_nil
456
- end
457
-
458
- it "sets project_id when the PROJECT_ID_VAR env var is set" do
459
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
460
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
461
- ENV[PROJECT_ID_VAR] = cred_json[:project_id]
462
- ENV[ENV_VAR] = nil
463
- credentials = clz.from_env @scope
464
- expect(credentials).to_not be_nil
465
- expect(credentials.project_id).to eq(cred_json[:project_id])
466
- end
467
- end
468
-
469
- describe "#from_well_known_path" do
470
- before :example do
471
- @home = ENV["HOME"]
472
- @app_data = ENV["APPDATA"]
473
- end
474
-
475
- after :example do
476
- ENV["HOME"] = @home unless @home == ENV["HOME"]
477
- ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
478
- end
479
-
480
- it "is nil if no file exists" do
481
- ENV["HOME"] = File.dirname __FILE__
482
- expect(clz.from_well_known_path).to be_nil
483
- end
484
-
485
- it "successfully loads the file when it is present" do
486
- Dir.mktmpdir do |dir|
487
- key_path = File.join dir, ".config", WELL_KNOWN_PATH
488
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
489
- FileUtils.mkdir_p File.dirname(key_path)
490
- File.write key_path, cred_json_text
491
- ENV["HOME"] = dir
492
- ENV["APPDATA"] = dir
493
- expect(clz.from_well_known_path).to_not be_nil
494
- end
495
- end
496
-
497
- it "successfully sets project_id when file is present" do
498
- Dir.mktmpdir do |dir|
499
- key_path = File.join dir, ".config", WELL_KNOWN_PATH
500
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
501
- FileUtils.mkdir_p File.dirname(key_path)
502
- File.write key_path, cred_json_text
503
- ENV["HOME"] = dir
504
- ENV["APPDATA"] = dir
505
- credentials = clz.from_well_known_path @scope
506
- expect(credentials.project_id).to eq(cred_json[:project_id])
507
- expect(credentials.quota_project_id).to be_nil
508
- end
509
- end
510
- end
511
- end
@@ -1,142 +0,0 @@
1
- # Copyright 2015, Google Inc.
2
- # All rights reserved.
3
- #
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are
6
- # met:
7
- #
8
- # * Redistributions of source code must retain the above copyright
9
- # notice, this list of conditions and the following disclaimer.
10
- # * Redistributions in binary form must reproduce the above
11
- # copyright notice, this list of conditions and the following disclaimer
12
- # in the documentation and/or other materials provided with the
13
- # distribution.
14
- # * Neither the name of Google Inc. nor the names of its
15
- # contributors may be used to endorse or promote products derived from
16
- # this software without specific prior written permission.
17
- #
18
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- spec_dir = File.expand_path File.join(File.dirname(__FILE__))
31
- $LOAD_PATH.unshift spec_dir
32
- $LOAD_PATH.uniq!
33
-
34
- require "apply_auth_examples"
35
- require "googleauth/signet"
36
- require "jwt"
37
- require "openssl"
38
- require "spec_helper"
39
-
40
- describe Signet::OAuth2::Client do
41
- before :example do
42
- @key = OpenSSL::PKey::RSA.new 2048
43
- @client = Signet::OAuth2::Client.new(
44
- token_credential_uri: "https://oauth2.googleapis.com/token",
45
- scope: "https://www.googleapis.com/auth/userinfo.profile",
46
- issuer: "app@example.com",
47
- audience: "https://oauth2.googleapis.com/token",
48
- signing_key: @key
49
- )
50
- @id_client = Signet::OAuth2::Client.new(
51
- token_credential_uri: "https://oauth2.googleapis.com/token",
52
- target_audience: "https://pubsub.googleapis.com/",
53
- issuer: "app@example.com",
54
- audience: "https://oauth2.googleapis.com/token",
55
- signing_key: @key
56
- )
57
- end
58
-
59
- def make_auth_stubs opts
60
- body_fields = { "token_type" => "Bearer", "expires_in" => 3600 }
61
- body_fields["access_token"] = opts[:access_token] if opts[:access_token]
62
- body_fields["id_token"] = opts[:id_token] if opts[:id_token]
63
- body = MultiJson.dump body_fields
64
- blk = proc do |request|
65
- params = Addressable::URI.form_unencode request.body
66
- claim, _header = JWT.decode(params.assoc("assertion").last,
67
- @key.public_key, true,
68
- algorithm: "RS256")
69
- !opts[:id_token] || claim["target_audience"] == "https://pubsub.googleapis.com/"
70
- end
71
- with_params = { body: hash_including(
72
- "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer"
73
- ) }
74
- with_params[:headers] = { "User-Agent" => opts[:user_agent] } if opts[:user_agent]
75
- stub_request(:post, "https://oauth2.googleapis.com/token")
76
- .with(with_params, &blk)
77
- .to_return(body: body,
78
- status: 200,
79
- headers: { "Content-Type" => "application/json" })
80
- end
81
-
82
- it_behaves_like "apply/apply! are OK"
83
-
84
- describe "#configure_connection" do
85
- it "honors default_connection" do
86
- token = "1/abcdef1234567890"
87
- stub = make_auth_stubs access_token: token, user_agent: "RubyRocks/1.0"
88
- conn = Faraday.new headers: { "User-Agent" => "RubyRocks/1.0" }
89
- @client.configure_connection default_connection: conn
90
- md = { foo: "bar" }
91
- @client.apply! md
92
- want = { foo: "bar", authorization: "Bearer #{token}" }
93
- expect(md).to eq(want)
94
- expect(stub).to have_been_requested
95
- end
96
-
97
- it "honors connection_builder" do
98
- token = "1/abcdef1234567890"
99
- stub = make_auth_stubs access_token: token, user_agent: "RubyRocks/2.0"
100
- connection_builder = proc do
101
- Faraday.new headers: { "User-Agent" => "RubyRocks/2.0" }
102
- end
103
- @client.configure_connection connection_builder: connection_builder
104
- md = { foo: "bar" }
105
- @client.apply! md
106
- want = { foo: "bar", authorization: "Bearer #{token}" }
107
- expect(md).to eq(want)
108
- expect(stub).to have_been_requested
109
- end
110
- end
111
-
112
- describe "#fetch_access_token!" do
113
- it "retries when orig_fetch_access_token! raises Signet::RemoteServerError" do
114
- mocked_responses = [:raise, :raise, "success"]
115
- allow(@client).to receive(:orig_fetch_access_token!).exactly(3).times do
116
- response = mocked_responses.shift
117
- response == :raise ? raise(Signet::RemoteServerError) : response
118
- end
119
- expect(@client.fetch_access_token!).to eq("success")
120
- end
121
-
122
- it "raises when the max retry count is exceeded" do
123
- mocked_responses = [:raise, :raise, :raise, :raise, :raise, :raise, "success"]
124
- allow(@client).to receive(:orig_fetch_access_token!).exactly(6).times do
125
- response = mocked_responses.shift
126
- response == :raise ? raise(Signet::RemoteServerError) : response
127
- end
128
- expect { @client.fetch_access_token! }.to raise_error Signet::AuthorizationError
129
- end
130
-
131
- it "does not retry and raises right away if it encounters a Signet::AuthorizationError" do
132
- allow(@client).to receive(:orig_fetch_access_token!).at_most(:once)
133
- .and_raise(Signet::AuthorizationError.new("Some Message"))
134
- expect { @client.fetch_access_token! }.to raise_error Signet::AuthorizationError
135
- end
136
-
137
- it "does not retry and raises right away if it encounters a Signet::ParseError" do
138
- allow(@client).to receive(:orig_fetch_access_token!).at_most(:once).and_raise(Signet::ParseError)
139
- expect { @client.fetch_access_token! }.to raise_error Signet::ParseError
140
- end
141
- end
142
- end