googleauth 0.11.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +7 -0
- data/.github/workflows/release.yml +36 -0
- data/.rubocop.yml +3 -1
- data/CHANGELOG.md +59 -23
- data/Gemfile +5 -2
- data/{COPYING → LICENSE} +0 -0
- data/Rakefile +21 -0
- data/googleauth.gemspec +3 -2
- data/integration/helper.rb +31 -0
- data/integration/id_tokens/key_source_test.rb +74 -0
- data/lib/googleauth.rb +1 -0
- data/lib/googleauth/application_default.rb +1 -1
- data/lib/googleauth/compute_engine.rb +40 -9
- data/lib/googleauth/credentials.rb +217 -54
- data/lib/googleauth/id_tokens.rb +233 -0
- data/lib/googleauth/id_tokens/errors.rb +71 -0
- data/lib/googleauth/id_tokens/key_sources.rb +394 -0
- data/lib/googleauth/id_tokens/verifier.rb +144 -0
- data/lib/googleauth/json_key_reader.rb +6 -2
- data/lib/googleauth/service_account.rb +39 -20
- data/lib/googleauth/signet.rb +3 -2
- data/lib/googleauth/version.rb +1 -1
- data/lib/googleauth/web_user_authorizer.rb +3 -6
- data/spec/googleauth/apply_auth_examples.rb +28 -5
- data/spec/googleauth/compute_engine_spec.rb +66 -13
- data/spec/googleauth/credentials_spec.rb +240 -112
- data/spec/googleauth/service_account_spec.rb +31 -16
- data/spec/googleauth/signet_spec.rb +15 -7
- data/spec/googleauth/user_refresh_spec.rb +1 -1
- data/test/helper.rb +33 -0
- data/test/id_tokens/key_sources_test.rb +240 -0
- data/test/id_tokens/verifier_test.rb +269 -0
- metadata +18 -7
@@ -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"
|
40
|
-
"private_key"
|
41
|
-
"client_email"
|
42
|
-
"client_id"
|
43
|
-
"type"
|
44
|
-
"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
|
-
|
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
|
-
|
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 =
|
104
|
-
|
105
|
-
allow(
|
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[:
|
112
|
-
expect(options[:
|
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
|
-
|
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") {
|
141
|
+
allow(::File).to receive(:read).with("/unknown/path/to/file.txt") { json_content }
|
142
|
+
|
143
|
+
mocked_signet = mock_signet
|
137
144
|
|
138
|
-
|
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[:
|
147
|
-
expect(options[:
|
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
|
-
|
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 =
|
176
|
-
|
177
|
-
allow(
|
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[:
|
184
|
-
expect(options[:
|
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
|
-
|
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") {
|
219
|
+
allow(::File).to receive(:read).with("~/default/path/to/file.txt") { json_content }
|
209
220
|
|
210
|
-
mocked_signet =
|
211
|
-
|
212
|
-
allow(
|
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[:
|
219
|
-
expect(options[:
|
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
|
-
|
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 =
|
245
|
-
|
246
|
-
allow(
|
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 =
|
291
|
-
|
292
|
-
allow(
|
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[:
|
299
|
-
expect(options[:
|
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
|
-
|
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") {
|
357
|
+
allow(::File).to receive(:read).with("/unknown/path/to/file.txt") { json_content }
|
358
|
+
|
359
|
+
mocked_signet = mock_signet
|
323
360
|
|
324
|
-
|
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[:
|
333
|
-
expect(options[:
|
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
|
-
|
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 =
|
361
|
-
|
362
|
-
allow(
|
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[:
|
369
|
-
expect(options[:
|
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
|
-
|
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") {
|
433
|
+
allow(::File).to receive(:read).with("~/default/path/to/file.txt") { json_content }
|
434
|
+
|
435
|
+
mocked_signet = mock_signet
|
393
436
|
|
394
|
-
|
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[:
|
403
|
-
expect(options[:
|
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
|
-
|
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 =
|
428
|
-
|
429
|
-
allow(
|
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
|
-
|
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
|
-
|
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 =
|
449
|
-
expect(creds).to be_a_kind_of(
|
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
|
|