googleauth 0.11.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -36,46 +36,47 @@ require "googleauth"
36
36
  describe Google::Auth::Credentials, :private do
37
37
  let :default_keyfile_hash do
38
38
  {
39
- "private_key_id" => "testabc1234567890xyz",
40
- "private_key" => "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBAOyi0Hy1l4Ym2m2o71Q0TF4O9E81isZEsX0bb+Bqz1SXEaSxLiXM\nUZE8wu0eEXivXuZg6QVCW/5l+f2+9UPrdNUCAwEAAQJAJkqubA/Chj3RSL92guy3\nktzeodarLyw8gF8pOmpuRGSiEo/OLTeRUMKKD1/kX4f9sxf3qDhB4e7dulXR1co/\nIQIhAPx8kMW4XTTL6lJYd2K5GrH8uBMp8qL5ya3/XHrBgw3dAiEA7+3Iw3ULTn2I\n1J34WlJ2D5fbzMzB4FAHUNEV7Ys3f1kCIQDtUahCMChrl7+H5t9QS+xrn77lRGhs\nB50pjvy95WXpgQIhAI2joW6JzTfz8fAapb+kiJ/h9Vcs1ZN3iyoRlNFb61JZAiA8\nNy5NyNrMVwtB/lfJf1dAK/p/Bwd8LZLtgM6PapRfgw==\n-----END RSA PRIVATE KEY-----\n",
41
- "client_email" => "credz-testabc1234567890xyz@developer.gserviceaccount.com",
42
- "client_id" => "credz-testabc1234567890xyz.apps.googleusercontent.com",
43
- "type" => "service_account",
44
- "project_id" => "a_project_id"
39
+ "private_key_id" => "testabc1234567890xyz",
40
+ "private_key" => "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBAOyi0Hy1l4Ym2m2o71Q0TF4O9E81isZEsX0bb+Bqz1SXEaSxLiXM\nUZE8wu0eEXivXuZg6QVCW/5l+f2+9UPrdNUCAwEAAQJAJkqubA/Chj3RSL92guy3\nktzeodarLyw8gF8pOmpuRGSiEo/OLTeRUMKKD1/kX4f9sxf3qDhB4e7dulXR1co/\nIQIhAPx8kMW4XTTL6lJYd2K5GrH8uBMp8qL5ya3/XHrBgw3dAiEA7+3Iw3ULTn2I\n1J34WlJ2D5fbzMzB4FAHUNEV7Ys3f1kCIQDtUahCMChrl7+H5t9QS+xrn77lRGhs\nB50pjvy95WXpgQIhAI2joW6JzTfz8fAapb+kiJ/h9Vcs1ZN3iyoRlNFb61JZAiA8\nNy5NyNrMVwtB/lfJf1dAK/p/Bwd8LZLtgM6PapRfgw==\n-----END RSA PRIVATE KEY-----\n",
41
+ "client_email" => "credz-testabc1234567890xyz@developer.gserviceaccount.com",
42
+ "client_id" => "credz-testabc1234567890xyz.apps.googleusercontent.com",
43
+ "type" => "service_account",
44
+ "project_id" => "a_project_id",
45
+ "quota_project_id" => "b_project_id"
45
46
  }
46
47
  end
47
48
 
48
- it "uses a default scope" do
49
+ def mock_signet
49
50
  mocked_signet = double "Signet::OAuth2::Client"
50
51
  allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
51
52
  allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
52
53
  allow(mocked_signet).to receive(:client_id)
53
54
  allow(Signet::OAuth2::Client).to receive(:new) do |options|
55
+ yield options if block_given?
56
+ mocked_signet
57
+ end
58
+ mocked_signet
59
+ end
60
+
61
+ it "uses a default scope" do
62
+ mock_signet do |options|
54
63
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
55
64
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
56
65
  expect(options[:scope]).to eq([])
57
66
  expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
58
67
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
59
-
60
- mocked_signet
61
68
  end
62
69
 
63
70
  Google::Auth::Credentials.new default_keyfile_hash
64
71
  end
65
72
 
66
73
  it "uses a custom scope" do
67
- mocked_signet = double "Signet::OAuth2::Client"
68
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
69
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
70
- allow(mocked_signet).to receive(:client_id)
71
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
74
+ mock_signet do |options|
72
75
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
73
76
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
74
77
  expect(options[:scope]).to eq(["http://example.com/scope"])
75
78
  expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
76
79
  expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
77
-
78
- mocked_signet
79
80
  end
80
81
 
81
82
  Google::Auth::Credentials.new default_keyfile_hash, scope: "http://example.com/scope"
@@ -100,24 +101,26 @@ describe Google::Auth::Credentials, :private do
100
101
  allow(::File).to receive(:file?).with(test_path_env_val) { false }
101
102
  allow(::File).to receive(:file?).with(test_json_env_val) { false }
102
103
 
103
- mocked_signet = double "Signet::OAuth2::Client"
104
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
105
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
106
- allow(mocked_signet).to receive(:client_id)
107
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
104
+ mocked_signet = mock_signet
105
+
106
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
108
107
  expect(options[:token_credential_uri]).to eq("https://example.com/token")
109
108
  expect(options[:audience]).to eq("https://example.com/audience")
110
109
  expect(options[:scope]).to eq(["http://example.com/scope"])
111
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
112
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
110
+ expect(options[:enable_self_signed_jwt]).to eq(true)
111
+ expect(options[:target_audience]).to be_nil
112
+ expect(options[:json_key_io].read).to eq(test_json_env_val)
113
113
 
114
- mocked_signet
114
+ # This should really be a Signet::OAuth2::Client object,
115
+ # but mocking is making that difficult, so return a valid hash instead.
116
+ default_keyfile_hash
115
117
  end
116
118
 
117
- creds = TestCredentials1.default
119
+ creds = TestCredentials1.default enable_self_signed_jwt: true
118
120
  expect(creds).to be_a_kind_of(TestCredentials1)
119
121
  expect(creds.client).to eq(mocked_signet)
120
122
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
123
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
121
124
  end
122
125
 
123
126
  it "subclasses can use PATH_ENV_VARS to get keyfile path" do
@@ -128,31 +131,35 @@ describe Google::Auth::Credentials, :private do
128
131
  DEFAULT_PATHS = ["~/default/path/to/file.txt"].freeze
129
132
  end
130
133
 
134
+ json_content = JSON.generate default_keyfile_hash
135
+
131
136
  allow(::ENV).to receive(:[]).with("GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS") { "true" }
132
137
  allow(::ENV).to receive(:[]).with("PATH_ENV_DUMMY") { "/fake/path/to/file.txt" }
133
138
  allow(::File).to receive(:file?).with("/fake/path/to/file.txt") { false }
134
139
  allow(::ENV).to receive(:[]).with("PATH_ENV_TEST") { "/unknown/path/to/file.txt" }
135
140
  allow(::File).to receive(:file?).with("/unknown/path/to/file.txt") { true }
136
- allow(::File).to receive(:read).with("/unknown/path/to/file.txt") { JSON.generate default_keyfile_hash }
141
+ allow(::File).to receive(:read).with("/unknown/path/to/file.txt") { json_content }
142
+
143
+ mocked_signet = mock_signet
137
144
 
138
- mocked_signet = double "Signet::OAuth2::Client"
139
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
140
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
141
- allow(mocked_signet).to receive(:client_id)
142
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
145
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
143
146
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
144
147
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
145
148
  expect(options[:scope]).to eq(["http://example.com/scope"])
146
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
147
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
149
+ expect(options[:enable_self_signed_jwt]).to be_nil
150
+ expect(options[:target_audience]).to be_nil
151
+ expect(options[:json_key_io].read).to eq(json_content)
148
152
 
149
- mocked_signet
153
+ # This should really be a Signet::OAuth2::Client object,
154
+ # but mocking is making that difficult, so return a valid hash instead.
155
+ default_keyfile_hash
150
156
  end
151
157
 
152
158
  creds = TestCredentials2.default
153
159
  expect(creds).to be_a_kind_of(TestCredentials2)
154
160
  expect(creds.client).to eq(mocked_signet)
155
161
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
162
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
156
163
  end
157
164
 
158
165
  it "subclasses can use JSON_ENV_VARS to get keyfile contents" do
@@ -172,24 +179,26 @@ describe Google::Auth::Credentials, :private do
172
179
  allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
173
180
  allow(::ENV).to receive(:[]).with("JSON_ENV_TEST") { test_json_env_val }
174
181
 
175
- mocked_signet = double "Signet::OAuth2::Client"
176
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
177
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
178
- allow(mocked_signet).to receive(:client_id)
179
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
182
+ mocked_signet = mock_signet
183
+
184
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
180
185
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
181
186
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
182
187
  expect(options[:scope]).to eq(["http://example.com/scope"])
183
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
184
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
188
+ expect(options[:enable_self_signed_jwt]).to be_nil
189
+ expect(options[:target_audience]).to be_nil
190
+ expect(options[:json_key_io].read).to eq(test_json_env_val)
185
191
 
186
- mocked_signet
192
+ # This should really be a Signet::OAuth2::Client object,
193
+ # but mocking is making that difficult, so return a valid hash instead.
194
+ default_keyfile_hash
187
195
  end
188
196
 
189
197
  creds = TestCredentials3.default
190
198
  expect(creds).to be_a_kind_of(TestCredentials3)
191
199
  expect(creds.client).to eq(mocked_signet)
192
200
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
201
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
193
202
  end
194
203
 
195
204
  it "subclasses can use DEFAULT_PATHS to get keyfile path" do
@@ -200,31 +209,35 @@ describe Google::Auth::Credentials, :private do
200
209
  DEFAULT_PATHS = ["~/default/path/to/file.txt"].freeze
201
210
  end
202
211
 
212
+ json_content = JSON.generate default_keyfile_hash
213
+
203
214
  allow(::ENV).to receive(:[]).with("GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS") { "true" }
204
215
  allow(::ENV).to receive(:[]).with("PATH_ENV_DUMMY") { "/fake/path/to/file.txt" }
205
216
  allow(::File).to receive(:file?).with("/fake/path/to/file.txt") { false }
206
217
  allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
207
218
  allow(::File).to receive(:file?).with("~/default/path/to/file.txt") { true }
208
- allow(::File).to receive(:read).with("~/default/path/to/file.txt") { JSON.generate default_keyfile_hash }
219
+ allow(::File).to receive(:read).with("~/default/path/to/file.txt") { json_content }
209
220
 
210
- mocked_signet = double "Signet::OAuth2::Client"
211
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
212
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
213
- allow(mocked_signet).to receive(:client_id)
214
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
221
+ mocked_signet = mock_signet
222
+
223
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
215
224
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
216
225
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
217
226
  expect(options[:scope]).to eq(["http://example.com/scope"])
218
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
219
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
227
+ expect(options[:enable_self_signed_jwt]).to be_nil
228
+ expect(options[:target_audience]).to be_nil
229
+ expect(options[:json_key_io].read).to eq(json_content)
220
230
 
221
- mocked_signet
231
+ # This should really be a Signet::OAuth2::Client object,
232
+ # but mocking is making that difficult, so return a valid hash instead.
233
+ default_keyfile_hash
222
234
  end
223
235
 
224
236
  creds = TestCredentials4.default
225
237
  expect(creds).to be_a_kind_of(TestCredentials4)
226
238
  expect(creds.client).to eq(mocked_signet)
227
239
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
240
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
228
241
  end
229
242
 
230
243
  it "subclasses that find no matches default to Google::Auth.get_application_default" do
@@ -241,31 +254,49 @@ describe Google::Auth::Credentials, :private do
241
254
  allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
242
255
  allow(::File).to receive(:file?).with("~/default/path/to/file.txt") { false }
243
256
 
244
- mocked_signet = double "Signet::OAuth2::Client"
245
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
246
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
247
- allow(mocked_signet).to receive(:client_id)
248
- allow(Google::Auth).to receive(:get_application_default) do |scope|
257
+ mocked_signet = mock_signet
258
+
259
+ allow(Google::Auth).to receive(:get_application_default) do |scope, options|
249
260
  expect(scope).to eq([TestCredentials5::SCOPE])
261
+ expect(options[:enable_self_signed_jwt]).to be_nil
262
+ expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
263
+ expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
250
264
 
251
265
  # This should really be a Signet::OAuth2::Client object,
252
266
  # but mocking is making that difficult, so return a valid hash instead.
253
267
  default_keyfile_hash
254
268
  end
255
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
256
- expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
257
- expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
258
- expect(options[:scope]).to eq(["http://example.com/scope"])
259
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
260
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
261
-
262
- mocked_signet
263
- end
264
269
 
265
270
  creds = TestCredentials5.default
266
271
  expect(creds).to be_a_kind_of(TestCredentials5)
267
272
  expect(creds.client).to eq(mocked_signet)
268
273
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
274
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
275
+ end
276
+
277
+ it "can be subclassed to pass in other env paths" do
278
+ class TestCredentials6 < Google::Auth::Credentials
279
+ TOKEN_CREDENTIAL_URI = "https://example.com/token".freeze
280
+ AUDIENCE = "https://example.com/audience".freeze
281
+ SCOPE = "http://example.com/scope".freeze
282
+ PATH_ENV_VARS = ["TEST_PATH"].freeze
283
+ JSON_ENV_VARS = ["TEST_JSON_VARS"].freeze
284
+ DEFAULT_PATHS = ["~/default/path/to/file.txt"]
285
+ end
286
+
287
+ class TestCredentials7 < TestCredentials6
288
+ end
289
+
290
+ expect(TestCredentials7.token_credential_uri).to eq("https://example.com/token")
291
+ expect(TestCredentials7.audience).to eq("https://example.com/audience")
292
+ expect(TestCredentials7.scope).to eq(["http://example.com/scope"])
293
+ expect(TestCredentials7.env_vars).to eq(["TEST_PATH", "TEST_JSON_VARS"])
294
+ expect(TestCredentials7.paths).to eq(["~/default/path/to/file.txt"])
295
+
296
+ TestCredentials7::TOKEN_CREDENTIAL_URI = "https://example.com/token2"
297
+ expect(TestCredentials7.token_credential_uri).to eq("https://example.com/token2")
298
+ TestCredentials7::AUDIENCE = nil
299
+ expect(TestCredentials7.audience).to eq("https://example.com/audience")
269
300
  end
270
301
  end
271
302
 
@@ -287,24 +318,26 @@ describe Google::Auth::Credentials, :private do
287
318
  allow(::File).to receive(:file?).with(test_path_env_val) { false }
288
319
  allow(::File).to receive(:file?).with(test_json_env_val) { false }
289
320
 
290
- mocked_signet = double "Signet::OAuth2::Client"
291
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
292
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
293
- allow(mocked_signet).to receive(:client_id)
294
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
321
+ mocked_signet = mock_signet
322
+
323
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
295
324
  expect(options[:token_credential_uri]).to eq("https://example.com/token")
296
325
  expect(options[:audience]).to eq("https://example.com/audience")
297
326
  expect(options[:scope]).to eq(["http://example.com/scope"])
298
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
299
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
327
+ expect(options[:enable_self_signed_jwt]).to be_nil
328
+ expect(options[:target_audience]).to be_nil
329
+ expect(options[:json_key_io].read).to eq(test_json_env_val)
300
330
 
301
- mocked_signet
331
+ # This should really be a Signet::OAuth2::Client object,
332
+ # but mocking is making that difficult, so return a valid hash instead.
333
+ default_keyfile_hash
302
334
  end
303
335
 
304
336
  creds = TestCredentials11.default
305
337
  expect(creds).to be_a_kind_of(TestCredentials11)
306
338
  expect(creds.client).to eq(mocked_signet)
307
339
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
340
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
308
341
  end
309
342
 
310
343
  it "subclasses can use PATH_ENV_VARS to get keyfile path" do
@@ -314,31 +347,35 @@ describe Google::Auth::Credentials, :private do
314
347
  self.paths = ["~/default/path/to/file.txt"]
315
348
  end
316
349
 
350
+ json_content = JSON.generate default_keyfile_hash
351
+
317
352
  allow(::ENV).to receive(:[]).with("GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS") { "true" }
318
353
  allow(::ENV).to receive(:[]).with("PATH_ENV_DUMMY") { "/fake/path/to/file.txt" }
319
354
  allow(::File).to receive(:file?).with("/fake/path/to/file.txt") { false }
320
355
  allow(::ENV).to receive(:[]).with("PATH_ENV_TEST") { "/unknown/path/to/file.txt" }
321
356
  allow(::File).to receive(:file?).with("/unknown/path/to/file.txt") { true }
322
- allow(::File).to receive(:read).with("/unknown/path/to/file.txt") { JSON.generate default_keyfile_hash }
357
+ allow(::File).to receive(:read).with("/unknown/path/to/file.txt") { json_content }
358
+
359
+ mocked_signet = mock_signet
323
360
 
324
- mocked_signet = double "Signet::OAuth2::Client"
325
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
326
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
327
- allow(mocked_signet).to receive(:client_id)
328
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
361
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
329
362
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
330
363
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
331
364
  expect(options[:scope]).to eq(["http://example.com/scope"])
332
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
333
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
365
+ expect(options[:enable_self_signed_jwt]).to be_nil
366
+ expect(options[:target_audience]).to be_nil
367
+ expect(options[:json_key_io].read).to eq(json_content)
334
368
 
335
- mocked_signet
369
+ # This should really be a Signet::OAuth2::Client object,
370
+ # but mocking is making that difficult, so return a valid hash instead.
371
+ default_keyfile_hash
336
372
  end
337
373
 
338
374
  creds = TestCredentials12.default
339
375
  expect(creds).to be_a_kind_of(TestCredentials12)
340
376
  expect(creds.client).to eq(mocked_signet)
341
377
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
378
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
342
379
  end
343
380
 
344
381
  it "subclasses can use JSON_ENV_VARS to get keyfile contents" do
@@ -357,24 +394,26 @@ describe Google::Auth::Credentials, :private do
357
394
  allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
358
395
  allow(::ENV).to receive(:[]).with("JSON_ENV_TEST") { test_json_env_val }
359
396
 
360
- mocked_signet = double "Signet::OAuth2::Client"
361
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
362
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
363
- allow(mocked_signet).to receive(:client_id)
364
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
397
+ mocked_signet = mock_signet
398
+
399
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
365
400
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
366
401
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
367
402
  expect(options[:scope]).to eq(["http://example.com/scope"])
368
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
369
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
403
+ expect(options[:enable_self_signed_jwt]).to be_nil
404
+ expect(options[:target_audience]).to be_nil
405
+ expect(options[:json_key_io].read).to eq(test_json_env_val)
370
406
 
371
- mocked_signet
407
+ # This should really be a Signet::OAuth2::Client object,
408
+ # but mocking is making that difficult, so return a valid hash instead.
409
+ default_keyfile_hash
372
410
  end
373
411
 
374
412
  creds = TestCredentials13.default
375
413
  expect(creds).to be_a_kind_of(TestCredentials13)
376
414
  expect(creds.client).to eq(mocked_signet)
377
415
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
416
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
378
417
  end
379
418
 
380
419
  it "subclasses can use DEFAULT_PATHS to get keyfile path" do
@@ -384,34 +423,38 @@ describe Google::Auth::Credentials, :private do
384
423
  self.paths = ["~/default/path/to/file.txt"]
385
424
  end
386
425
 
426
+ json_content = JSON.generate default_keyfile_hash
427
+
387
428
  allow(::ENV).to receive(:[]).with("GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS") { "true" }
388
429
  allow(::ENV).to receive(:[]).with("PATH_ENV_DUMMY") { "/fake/path/to/file.txt" }
389
430
  allow(::File).to receive(:file?).with("/fake/path/to/file.txt") { false }
390
431
  allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
391
432
  allow(::File).to receive(:file?).with("~/default/path/to/file.txt") { true }
392
- allow(::File).to receive(:read).with("~/default/path/to/file.txt") { JSON.generate default_keyfile_hash }
433
+ allow(::File).to receive(:read).with("~/default/path/to/file.txt") { json_content }
434
+
435
+ mocked_signet = mock_signet
393
436
 
394
- mocked_signet = double "Signet::OAuth2::Client"
395
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
396
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
397
- allow(mocked_signet).to receive(:client_id)
398
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
437
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds) do |options|
399
438
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
400
439
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
401
440
  expect(options[:scope]).to eq(["http://example.com/scope"])
402
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
403
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
441
+ expect(options[:enable_self_signed_jwt]).to be_nil
442
+ expect(options[:target_audience]).to be_nil
443
+ expect(options[:json_key_io].read).to eq(json_content)
404
444
 
405
- mocked_signet
445
+ # This should really be a Signet::OAuth2::Client object,
446
+ # but mocking is making that difficult, so return a valid hash instead.
447
+ default_keyfile_hash
406
448
  end
407
449
 
408
450
  creds = TestCredentials14.default
409
451
  expect(creds).to be_a_kind_of(TestCredentials14)
410
452
  expect(creds.client).to eq(mocked_signet)
411
453
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
454
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
412
455
  end
413
456
 
414
- it "subclasses that find no matches default to Google::Auth.get_application_default" do
457
+ it "subclasses that find no matches default to Google::Auth.get_application_default with self-signed jwt enabled" do
415
458
  class TestCredentials15 < Google::Auth::Credentials
416
459
  self.scope = "http://example.com/scope"
417
460
  self.env_vars = %w[PATH_ENV_DUMMY JSON_ENV_DUMMY]
@@ -424,31 +467,116 @@ describe Google::Auth::Credentials, :private do
424
467
  allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
425
468
  allow(::File).to receive(:file?).with("~/default/path/to/file.txt") { false }
426
469
 
427
- mocked_signet = double "Signet::OAuth2::Client"
428
- allow(mocked_signet).to receive(:configure_connection).and_return(mocked_signet)
429
- allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
430
- allow(mocked_signet).to receive(:client_id)
431
- allow(Google::Auth).to receive(:get_application_default) do |scope|
470
+ mocked_signet = mock_signet
471
+
472
+ allow(Google::Auth).to receive(:get_application_default) do |scope, options|
432
473
  expect(scope).to eq(TestCredentials15.scope)
474
+ expect(options[:enable_self_signed_jwt]).to eq(true)
475
+ expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
476
+ expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
433
477
 
434
478
  # This should really be a Signet::OAuth2::Client object,
435
479
  # but mocking is making that difficult, so return a valid hash instead.
436
480
  default_keyfile_hash
437
481
  end
438
- allow(Signet::OAuth2::Client).to receive(:new) do |options|
482
+
483
+ creds = TestCredentials15.default enable_self_signed_jwt: true
484
+ expect(creds).to be_a_kind_of(TestCredentials15)
485
+ expect(creds.client).to eq(mocked_signet)
486
+ expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
487
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
488
+ end
489
+
490
+ it "subclasses that find no matches default to Google::Auth.get_application_default with self-signed jwt disabled" do
491
+ class TestCredentials16 < Google::Auth::Credentials
492
+ self.scope = "http://example.com/scope"
493
+ self.env_vars = %w[PATH_ENV_DUMMY JSON_ENV_DUMMY]
494
+ self.paths = ["~/default/path/to/file.txt"]
495
+ end
496
+
497
+ allow(::ENV).to receive(:[]).with("GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS") { "true" }
498
+ allow(::ENV).to receive(:[]).with("PATH_ENV_DUMMY") { "/fake/path/to/file.txt" }
499
+ allow(::File).to receive(:file?).with("/fake/path/to/file.txt") { false }
500
+ allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
501
+ allow(::File).to receive(:file?).with("~/default/path/to/file.txt") { false }
502
+
503
+ mocked_signet = mock_signet
504
+
505
+ allow(Google::Auth).to receive(:get_application_default) do |scope, options|
506
+ expect(scope).to eq(TestCredentials16.scope)
507
+ expect(options[:enable_self_signed_jwt]).to be_nil
439
508
  expect(options[:token_credential_uri]).to eq("https://oauth2.googleapis.com/token")
440
509
  expect(options[:audience]).to eq("https://oauth2.googleapis.com/token")
441
- expect(options[:scope]).to eq(["http://example.com/scope"])
442
- expect(options[:issuer]).to eq(default_keyfile_hash["client_email"])
443
- expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
444
510
 
445
- mocked_signet
511
+ # This should really be a Signet::OAuth2::Client object,
512
+ # but mocking is making that difficult, so return a valid hash instead.
513
+ default_keyfile_hash
446
514
  end
447
515
 
448
- creds = TestCredentials15.default
449
- expect(creds).to be_a_kind_of(TestCredentials15)
516
+ creds = TestCredentials16.default
517
+ expect(creds).to be_a_kind_of(TestCredentials16)
450
518
  expect(creds.client).to eq(mocked_signet)
451
519
  expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
520
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
521
+ end
522
+
523
+ it "subclasses that find no matches default to Google::Auth.get_application_default with custom values" do
524
+ scope2 = "http://example.com/scope2"
525
+
526
+ class TestCredentials17 < Google::Auth::Credentials
527
+ self.scope = "http://example.com/scope"
528
+ self.env_vars = %w[PATH_ENV_DUMMY JSON_ENV_DUMMY]
529
+ self.paths = ["~/default/path/to/file.txt"]
530
+ self.token_credential_uri = "https://example.com/token2"
531
+ self.audience = "https://example.com/token3"
532
+ end
533
+
534
+ allow(::ENV).to receive(:[]).with("GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS") { "true" }
535
+ allow(::ENV).to receive(:[]).with("PATH_ENV_DUMMY") { "/fake/path/to/file.txt" }
536
+ allow(::File).to receive(:file?).with("/fake/path/to/file.txt") { false }
537
+ allow(::ENV).to receive(:[]).with("JSON_ENV_DUMMY") { nil }
538
+ allow(::File).to receive(:file?).with("~/default/path/to/file.txt") { false }
539
+
540
+ mocked_signet = mock_signet
541
+
542
+ allow(Google::Auth).to receive(:get_application_default) do |scope, options|
543
+ expect(scope).to eq(scope2)
544
+ expect(options[:enable_self_signed_jwt]).to eq(false)
545
+ expect(options[:token_credential_uri]).to eq("https://example.com/token2")
546
+ expect(options[:audience]).to eq("https://example.com/token3")
547
+
548
+ # This should really be a Signet::OAuth2::Client object,
549
+ # but mocking is making that difficult, so return a valid hash instead.
550
+ default_keyfile_hash
551
+ end
552
+
553
+ creds = TestCredentials17.default scope: scope2, enable_self_signed_jwt: true
554
+ expect(creds).to be_a_kind_of(TestCredentials17)
555
+ expect(creds.client).to eq(mocked_signet)
556
+ expect(creds.project_id).to eq(default_keyfile_hash["project_id"])
557
+ expect(creds.quota_project_id).to eq(default_keyfile_hash["quota_project_id"])
558
+ end
559
+
560
+ it "subclasses delegate up the class hierarchy" do
561
+ class TestCredentials18 < Google::Auth::Credentials
562
+ self.scope = "http://example.com/scope"
563
+ self.target_audience = "https://example.com/target_audience"
564
+ self.env_vars = ["TEST_PATH", "TEST_JSON_VARS"]
565
+ self.paths = ["~/default/path/to/file.txt"]
566
+ end
567
+
568
+ class TestCredentials19 < TestCredentials18
569
+ end
570
+
571
+ expect(TestCredentials19.scope).to eq(["http://example.com/scope"])
572
+ expect(TestCredentials19.target_audience).to eq("https://example.com/target_audience")
573
+ expect(TestCredentials19.env_vars).to eq(["TEST_PATH", "TEST_JSON_VARS"])
574
+ expect(TestCredentials19.paths).to eq(["~/default/path/to/file.txt"])
575
+
576
+ TestCredentials19.token_credential_uri = "https://example.com/token2"
577
+ expect(TestCredentials19.token_credential_uri).to eq("https://example.com/token2")
578
+ TestCredentials19.token_credential_uri = nil
579
+ expect(TestCredentials19.token_credential_uri).to eq("https://oauth2.googleapis.com/token")
452
580
  end
453
581
  end
454
582