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