googleauth 0.14.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.md +72 -10
  4. data/README.md +48 -13
  5. data/SECURITY.md +7 -0
  6. data/lib/googleauth/application_default.rb +10 -25
  7. data/lib/googleauth/client_id.rb +10 -25
  8. data/lib/googleauth/compute_engine.rb +16 -30
  9. data/lib/googleauth/credentials.rb +178 -74
  10. data/lib/googleauth/credentials_loader.rb +23 -44
  11. data/lib/googleauth/default_credentials.rb +10 -25
  12. data/lib/googleauth/iam.rb +11 -26
  13. data/lib/googleauth/id_tokens/errors.rb +9 -23
  14. data/lib/googleauth/id_tokens/key_sources.rb +26 -38
  15. data/lib/googleauth/id_tokens/verifier.rb +16 -32
  16. data/lib/googleauth/id_tokens.rb +9 -23
  17. data/lib/googleauth/json_key_reader.rb +10 -25
  18. data/lib/googleauth/scope_util.rb +11 -26
  19. data/lib/googleauth/service_account.rb +60 -59
  20. data/lib/googleauth/signet.rb +22 -28
  21. data/lib/googleauth/stores/file_token_store.rb +11 -25
  22. data/lib/googleauth/stores/redis_token_store.rb +11 -25
  23. data/lib/googleauth/token_store.rb +10 -25
  24. data/lib/googleauth/user_authorizer.rb +10 -25
  25. data/lib/googleauth/user_refresh.rb +15 -27
  26. data/lib/googleauth/version.rb +11 -26
  27. data/lib/googleauth/web_user_authorizer.rb +14 -32
  28. data/lib/googleauth.rb +10 -25
  29. metadata +26 -97
  30. data/.github/CODEOWNERS +0 -7
  31. data/.github/CONTRIBUTING.md +0 -74
  32. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -36
  33. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -21
  34. data/.github/ISSUE_TEMPLATE/support_request.md +0 -7
  35. data/.gitignore +0 -36
  36. data/.kokoro/build.bat +0 -16
  37. data/.kokoro/build.sh +0 -4
  38. data/.kokoro/continuous/common.cfg +0 -24
  39. data/.kokoro/continuous/linux.cfg +0 -25
  40. data/.kokoro/continuous/osx.cfg +0 -8
  41. data/.kokoro/continuous/post.cfg +0 -30
  42. data/.kokoro/continuous/windows.cfg +0 -29
  43. data/.kokoro/osx.sh +0 -4
  44. data/.kokoro/presubmit/common.cfg +0 -24
  45. data/.kokoro/presubmit/linux.cfg +0 -24
  46. data/.kokoro/presubmit/osx.cfg +0 -8
  47. data/.kokoro/presubmit/windows.cfg +0 -29
  48. data/.kokoro/release.cfg +0 -94
  49. data/.kokoro/trampoline.bat +0 -10
  50. data/.kokoro/trampoline.sh +0 -4
  51. data/.repo-metadata.json +0 -5
  52. data/.rspec +0 -2
  53. data/.rubocop.yml +0 -19
  54. data/Gemfile +0 -30
  55. data/Rakefile +0 -132
  56. data/googleauth.gemspec +0 -38
  57. data/integration/helper.rb +0 -31
  58. data/integration/id_tokens/key_source_test.rb +0 -74
  59. data/rakelib/devsite_builder.rb +0 -45
  60. data/rakelib/link_checker.rb +0 -64
  61. data/rakelib/repo_metadata.rb +0 -59
  62. data/spec/googleauth/apply_auth_examples.rb +0 -171
  63. data/spec/googleauth/client_id_spec.rb +0 -160
  64. data/spec/googleauth/compute_engine_spec.rb +0 -160
  65. data/spec/googleauth/credentials_spec.rb +0 -478
  66. data/spec/googleauth/get_application_default_spec.rb +0 -286
  67. data/spec/googleauth/iam_spec.rb +0 -80
  68. data/spec/googleauth/scope_util_spec.rb +0 -77
  69. data/spec/googleauth/service_account_spec.rb +0 -489
  70. data/spec/googleauth/signet_spec.rb +0 -142
  71. data/spec/googleauth/stores/file_token_store_spec.rb +0 -57
  72. data/spec/googleauth/stores/redis_token_store_spec.rb +0 -50
  73. data/spec/googleauth/stores/store_examples.rb +0 -58
  74. data/spec/googleauth/user_authorizer_spec.rb +0 -343
  75. data/spec/googleauth/user_refresh_spec.rb +0 -359
  76. data/spec/googleauth/web_user_authorizer_spec.rb +0 -172
  77. data/spec/spec_helper.rb +0 -92
  78. data/test/helper.rb +0 -33
  79. data/test/id_tokens/key_sources_test.rb +0 -240
  80. data/test/id_tokens/verifier_test.rb +0 -269
@@ -1,489 +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
48
- context "when jwt_aud_uri is present" do
49
- let(:test_uri) { "https://www.googleapis.com/myservice" }
50
- let(:auth_prefix) { "Bearer " }
51
- let(:auth_key) { ServiceAccountJwtHeaderCredentials::AUTH_METADATA_KEY }
52
- let(:jwt_uri_key) { ServiceAccountJwtHeaderCredentials::JWT_AUD_URI_KEY }
53
-
54
- def expect_is_encoded_jwt hdr
55
- expect(hdr).to_not be_nil
56
- expect(hdr.start_with?(auth_prefix)).to be true
57
- authorization = hdr[auth_prefix.length..-1]
58
- payload, = JWT.decode authorization, @key.public_key, true, algorithm: "RS256"
59
- expect(payload["aud"]).to eq(test_uri)
60
- expect(payload["iss"]).to eq(client_email)
61
- end
62
-
63
- describe "#apply!" do
64
- it "should update the target hash with a jwt token" do
65
- md = { foo: "bar" }
66
- md[jwt_uri_key] = test_uri
67
- @client.apply! md
68
- auth_header = md[auth_key]
69
- expect_is_encoded_jwt auth_header
70
- expect(md[jwt_uri_key]).to be_nil
71
- end
72
- end
73
-
74
- describe "updater_proc" do
75
- it "should provide a proc that updates a hash with a jwt token" do
76
- md = { foo: "bar" }
77
- md[jwt_uri_key] = test_uri
78
- the_proc = @client.updater_proc
79
- got = the_proc.call md
80
- auth_header = got[auth_key]
81
- expect_is_encoded_jwt auth_header
82
- expect(got[jwt_uri_key]).to be_nil
83
- expect(md[jwt_uri_key]).to_not be_nil
84
- end
85
- end
86
-
87
- describe "#apply" do
88
- it "should not update the original hash with a jwt token" do
89
- md = { foo: "bar" }
90
- md[jwt_uri_key] = test_uri
91
- the_proc = @client.updater_proc
92
- got = the_proc.call md
93
- auth_header = md[auth_key]
94
- expect(auth_header).to be_nil
95
- expect(got[jwt_uri_key]).to be_nil
96
- expect(md[jwt_uri_key]).to_not be_nil
97
- end
98
-
99
- it "should add a jwt token to the returned hash" do
100
- md = { foo: "bar" }
101
- md[jwt_uri_key] = test_uri
102
- got = @client.apply md
103
- auth_header = got[auth_key]
104
- expect_is_encoded_jwt auth_header
105
- end
106
- end
107
- end
108
- end
109
-
110
- describe Google::Auth::ServiceAccountCredentials do
111
- ServiceAccountCredentials = Google::Auth::ServiceAccountCredentials
112
- let(:client_email) { "app@developer.gserviceaccount.com" }
113
- let :cred_json do
114
- {
115
- private_key_id: "a_private_key_id",
116
- private_key: @key.to_pem,
117
- client_email: client_email,
118
- client_id: "app.apps.googleusercontent.com",
119
- type: "service_account",
120
- project_id: "a_project_id",
121
- quota_project_id: "b_project_id"
122
- }
123
- end
124
-
125
- before :example do
126
- @key = OpenSSL::PKey::RSA.new 2048
127
- @client = ServiceAccountCredentials.make_creds(
128
- json_key_io: StringIO.new(cred_json_text),
129
- scope: "https://www.googleapis.com/auth/userinfo.profile"
130
- )
131
- @id_client = ServiceAccountCredentials.make_creds(
132
- json_key_io: StringIO.new(cred_json_text),
133
- target_audience: "https://pubsub.googleapis.com/"
134
- )
135
- end
136
-
137
- def make_auth_stubs opts
138
- body_fields = { "token_type" => "Bearer", "expires_in" => 3600 }
139
- body_fields["access_token"] = opts[:access_token] if opts[:access_token]
140
- body_fields["id_token"] = opts[:id_token] if opts[:id_token]
141
- body = MultiJson.dump body_fields
142
- blk = proc do |request|
143
- params = Addressable::URI.form_unencode request.body
144
- claim, _header = JWT.decode(params.assoc("assertion").last,
145
- @key.public_key, true,
146
- algorithm: "RS256")
147
- !opts[:id_token] || claim["target_audience"] == "https://pubsub.googleapis.com/"
148
- end
149
- stub_request(:post, "https://www.googleapis.com/oauth2/v4/token")
150
- .with(body: hash_including(
151
- "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer"
152
- ), &blk)
153
- .to_return(body: body,
154
- status: 200,
155
- headers: { "Content-Type" => "application/json" })
156
- end
157
-
158
- def cred_json_text
159
- MultiJson.dump cred_json
160
- end
161
-
162
- it_behaves_like "apply/apply! are OK"
163
-
164
- context "when scope is nil" do
165
- before :example do
166
- @client.scope = nil
167
- end
168
-
169
- it_behaves_like "jwt header auth"
170
- end
171
-
172
- describe "#from_env" do
173
- before :example do
174
- @var_name = ENV_VAR
175
- @credential_vars = [
176
- ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
177
- ]
178
- @original_env_vals = {}
179
- @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
180
- ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
181
-
182
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
183
- @clz = ServiceAccountCredentials
184
- end
185
-
186
- after :example do
187
- @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
188
- end
189
-
190
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
191
- ENV.delete @var_name unless ENV[@var_name].nil?
192
- expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
193
- end
194
-
195
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
196
- ENV[@var_name] = ""
197
- expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
198
- end
199
-
200
- it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
201
- ENV.delete @var_name unless ENV[@var_name].nil?
202
- expect(ServiceAccountCredentials.from_env(@scope)).to be_nil
203
- Dir.mktmpdir do |dir|
204
- key_path = File.join dir, "does-not-exist"
205
- ENV[@var_name] = key_path
206
- expect { @clz.from_env @scope }.to raise_error RuntimeError
207
- end
208
- end
209
-
210
- it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
211
- Dir.mktmpdir do |dir|
212
- key_path = File.join dir, "my_cert_file"
213
- FileUtils.mkdir_p File.dirname(key_path)
214
- File.write key_path, cred_json_text
215
- ENV[@var_name] = key_path
216
- expect(@clz.from_env(@scope)).to_not be_nil
217
- end
218
- end
219
-
220
- it "succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are"\
221
- " valid" do
222
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
223
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
224
- expect(@clz.from_env(@scope)).to_not be_nil
225
- end
226
-
227
- it "sets project_id when the PROJECT_ID_VAR env var is set" do
228
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
229
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
230
- ENV[PROJECT_ID_VAR] = cred_json[:project_id]
231
- ENV[ENV_VAR] = nil
232
- credentials = @clz.from_env @scope
233
- expect(credentials.project_id).to eq(cred_json[:project_id])
234
- end
235
-
236
- it "succeeds when GOOGLE_PRIVATE_KEY is escaped" do
237
- escaped_key = cred_json[:private_key].gsub "\n", '\n'
238
- ENV[PRIVATE_KEY_VAR] = "\"#{escaped_key}\""
239
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
240
- expect(@clz.from_env(@scope)).to_not be_nil
241
- end
242
-
243
- it "propagates default_connection option" do
244
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
245
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
246
- connection = Faraday.new headers: { "User-Agent" => "hello" }
247
- creds = @clz.from_env @scope, default_connection: connection
248
- expect(creds.build_default_connection).to be connection
249
- end
250
- end
251
-
252
- describe "#from_well_known_path" do
253
- before :example do
254
- @home = ENV["HOME"]
255
- @app_data = ENV["APPDATA"]
256
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
257
- @known_path = WELL_KNOWN_PATH
258
- @clz = ServiceAccountCredentials
259
- end
260
-
261
- after :example do
262
- ENV["HOME"] = @home unless @home == ENV["HOME"]
263
- ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
264
- end
265
-
266
- it "is nil if no file exists" do
267
- ENV["HOME"] = File.dirname __FILE__
268
- expect(ServiceAccountCredentials.from_well_known_path(@scope)).to be_nil
269
- end
270
-
271
- it "successfully loads the file when it is present" do
272
- Dir.mktmpdir do |dir|
273
- key_path = File.join dir, ".config", @known_path
274
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
275
- FileUtils.mkdir_p File.dirname(key_path)
276
- File.write key_path, cred_json_text
277
- ENV["HOME"] = dir
278
- ENV["APPDATA"] = dir
279
- expect(@clz.from_well_known_path(@scope)).to_not be_nil
280
- end
281
- end
282
-
283
- it "successfully sets project_id when file is present" do
284
- Dir.mktmpdir do |dir|
285
- key_path = File.join dir, ".config", @known_path
286
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
287
- FileUtils.mkdir_p File.dirname(key_path)
288
- File.write key_path, cred_json_text
289
- ENV["HOME"] = dir
290
- ENV["APPDATA"] = dir
291
- credentials = @clz.from_well_known_path @scope
292
- expect(credentials.project_id).to eq(cred_json[:project_id])
293
- expect(credentials.quota_project_id).to eq(cred_json[:quota_project_id])
294
- end
295
- end
296
-
297
- it "propagates default_connection option" do
298
- Dir.mktmpdir do |dir|
299
- key_path = File.join dir, ".config", @known_path
300
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
301
- FileUtils.mkdir_p File.dirname(key_path)
302
- File.write key_path, cred_json_text
303
- ENV["HOME"] = dir
304
- ENV["APPDATA"] = dir
305
- connection = Faraday.new headers: { "User-Agent" => "hello" }
306
- creds = @clz.from_well_known_path @scope, default_connection: connection
307
- expect(creds.build_default_connection).to be connection
308
- end
309
- end
310
- end
311
-
312
- describe "#from_system_default_path" do
313
- before :example do
314
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
315
- @program_data = ENV["ProgramData"]
316
- @prefix = OS.windows? ? "/etc/Google/Auth/" : "/etc/google/auth/"
317
- @path = File.join @prefix, CREDENTIALS_FILE_NAME
318
- @clz = ServiceAccountCredentials
319
- end
320
-
321
- after :example do
322
- ENV["ProgramData"] = @program_data
323
- end
324
-
325
- it "is nil if no file exists" do
326
- FakeFS do
327
- expect(ServiceAccountCredentials.from_system_default_path(@scope))
328
- .to be_nil
329
- end
330
- end
331
-
332
- it "successfully loads the file when it is present" do
333
- FakeFS do
334
- ENV["ProgramData"] = "/etc"
335
- FileUtils.mkdir_p File.dirname(@path)
336
- File.write @path, cred_json_text
337
- expect(@clz.from_system_default_path(@scope)).to_not be_nil
338
- File.delete @path
339
- end
340
- end
341
-
342
- it "propagates default_connection option" do
343
- FakeFS do
344
- ENV["ProgramData"] = "/etc"
345
- FileUtils.mkdir_p File.dirname(@path)
346
- File.write @path, cred_json_text
347
- connection = Faraday.new headers: { "User-Agent" => "hello" }
348
- creds = @clz.from_system_default_path @scope, default_connection: connection
349
- expect(creds.build_default_connection).to be connection
350
- File.delete @path
351
- end
352
- end
353
- end
354
- end
355
-
356
- describe Google::Auth::ServiceAccountJwtHeaderCredentials do
357
- ServiceAccountJwtHeaderCredentials =
358
- Google::Auth::ServiceAccountJwtHeaderCredentials
359
-
360
- let(:client_email) { "app@developer.gserviceaccount.com" }
361
- let(:clz) { Google::Auth::ServiceAccountJwtHeaderCredentials }
362
- let :cred_json do
363
- {
364
- private_key_id: "a_private_key_id",
365
- private_key: @key.to_pem,
366
- client_email: client_email,
367
- client_id: "app.apps.googleusercontent.com",
368
- type: "service_account",
369
- project_id: "a_project_id"
370
- }
371
- end
372
-
373
- before :example do
374
- @key = OpenSSL::PKey::RSA.new 2048
375
- @client = clz.make_creds json_key_io: StringIO.new(cred_json_text)
376
- end
377
-
378
- def cred_json_text
379
- MultiJson.dump cred_json
380
- end
381
-
382
- it_behaves_like "jwt header auth"
383
-
384
- describe "#from_env" do
385
- before :example do
386
- @var_name = ENV_VAR
387
- @credential_vars = [
388
- ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR
389
- ]
390
- @original_env_vals = {}
391
- @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
392
- ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
393
- end
394
-
395
- after :example do
396
- @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
397
- end
398
-
399
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
400
- ENV.delete @var_name unless ENV[@var_name].nil?
401
- expect(clz.from_env).to be_nil
402
- end
403
-
404
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
405
- ENV[@var_name] = ""
406
- expect(clz.from_env).to be_nil
407
- end
408
-
409
- it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
410
- ENV.delete @var_name unless ENV[@var_name].nil?
411
- expect(clz.from_env).to be_nil
412
- Dir.mktmpdir do |dir|
413
- key_path = File.join dir, "does-not-exist"
414
- ENV[@var_name] = key_path
415
- expect { clz.from_env }.to raise_error RuntimeError
416
- end
417
- end
418
-
419
- it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
420
- Dir.mktmpdir do |dir|
421
- key_path = File.join dir, "my_cert_file"
422
- FileUtils.mkdir_p File.dirname(key_path)
423
- File.write key_path, cred_json_text
424
- ENV[@var_name] = key_path
425
- expect(clz.from_env).to_not be_nil
426
- end
427
- end
428
-
429
- it "succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are"\
430
- " valid" do
431
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
432
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
433
- expect(clz.from_env(@scope)).to_not be_nil
434
- end
435
-
436
- it "sets project_id when the PROJECT_ID_VAR env var is set" do
437
- ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
438
- ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
439
- ENV[PROJECT_ID_VAR] = cred_json[:project_id]
440
- ENV[ENV_VAR] = nil
441
- credentials = clz.from_env @scope
442
- expect(credentials).to_not be_nil
443
- expect(credentials.project_id).to eq(cred_json[:project_id])
444
- end
445
- end
446
-
447
- describe "#from_well_known_path" do
448
- before :example do
449
- @home = ENV["HOME"]
450
- @app_data = ENV["APPDATA"]
451
- end
452
-
453
- after :example do
454
- ENV["HOME"] = @home unless @home == ENV["HOME"]
455
- ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
456
- end
457
-
458
- it "is nil if no file exists" do
459
- ENV["HOME"] = File.dirname __FILE__
460
- expect(clz.from_well_known_path).to be_nil
461
- end
462
-
463
- it "successfully loads the file when it is present" do
464
- Dir.mktmpdir do |dir|
465
- key_path = File.join dir, ".config", WELL_KNOWN_PATH
466
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
467
- FileUtils.mkdir_p File.dirname(key_path)
468
- File.write key_path, cred_json_text
469
- ENV["HOME"] = dir
470
- ENV["APPDATA"] = dir
471
- expect(clz.from_well_known_path).to_not be_nil
472
- end
473
- end
474
-
475
- it "successfully sets project_id when file is present" do
476
- Dir.mktmpdir do |dir|
477
- key_path = File.join dir, ".config", WELL_KNOWN_PATH
478
- key_path = File.join dir, WELL_KNOWN_PATH if OS.windows?
479
- FileUtils.mkdir_p File.dirname(key_path)
480
- File.write key_path, cred_json_text
481
- ENV["HOME"] = dir
482
- ENV["APPDATA"] = dir
483
- credentials = clz.from_well_known_path @scope
484
- expect(credentials.project_id).to eq(cred_json[:project_id])
485
- expect(credentials.quota_project_id).to be_nil
486
- end
487
- end
488
- end
489
- 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
@@ -1,57 +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 "googleauth"
35
- require "googleauth/stores/file_token_store"
36
- require "spec_helper"
37
- require "fakefs/safe"
38
- require "fakefs/spec_helpers"
39
- require "googleauth/stores/store_examples"
40
-
41
- module FakeFS
42
- class File
43
- # FakeFS doesn't implement. And since we don't need to actually lock,
44
- # just stub out...
45
- def flock *; end
46
- end
47
- end
48
-
49
- describe Google::Auth::Stores::FileTokenStore do
50
- include FakeFS::SpecHelpers
51
-
52
- let :store do
53
- Google::Auth::Stores::FileTokenStore.new file: "/tokens.yaml"
54
- end
55
-
56
- it_behaves_like "token store"
57
- end