@@ -142,13 +142,9 @@ func generateGoogleToken(keyFileName string) (string, error) {
142
142
return token .AccessToken , nil
143
143
}
144
144
145
- // testBYOID makes sure that the default credentials works for
146
- // whatever preconditions have been set beforehand
147
- // by using those credentials to run our client libraries.
148
- //
149
- // In each test we will set up whatever preconditions we need,
150
- // and then use this function.
151
- func testBYOID (t * testing.T , c config ) {
145
+ // writeConfig writes a temporary config file to memory, and cleans it up after
146
+ // testing code is run.
147
+ func writeConfig (t * testing.T , c config , f func (name string )) {
152
148
t .Helper ()
153
149
154
150
// Set up config file.
@@ -164,40 +160,59 @@ func testBYOID(t *testing.T, c config) {
164
160
}
165
161
configFile .Close ()
166
162
167
- // Once the default credentials are obtained,
168
- // we should be able to access Google Cloud resources.
169
- dnsService , err := dns .NewService (context .Background (), option .WithCredentialsFile (configFile .Name ()))
170
- if err != nil {
171
- t .Fatalf ("Could not establish DNS Service: %v" , err )
172
- }
163
+ f (configFile .Name ())
164
+ }
173
165
174
- _ , err = dnsService .Projects .Get (projectID ).Do ()
175
- if err != nil {
176
- t .Fatalf ("DNS Service failed: %v" , err )
177
- }
166
+ // testBYOID makes sure that the default credentials works for
167
+ // whatever preconditions have been set beforehand
168
+ // by using those credentials to run our client libraries.
169
+ //
170
+ // In each test we will set up whatever preconditions we need,
171
+ // and then use this function.
172
+ func testBYOID (t * testing.T , c config ) {
173
+ t .Helper ()
174
+
175
+ writeConfig (t , c , func (name string ) {
176
+ // Once the default credentials are obtained,
177
+ // we should be able to access Google Cloud resources.
178
+ dnsService , err := dns .NewService (context .Background (), option .WithCredentialsFile (name ))
179
+ if err != nil {
180
+ t .Fatalf ("Could not establish DNS Service: %v" , err )
181
+ }
182
+
183
+ _ , err = dnsService .Projects .Get (projectID ).Do ()
184
+ if err != nil {
185
+ t .Fatalf ("DNS Service failed: %v" , err )
186
+ }
187
+ })
178
188
}
179
189
180
190
// These structs makes writing our config as json to a file much easier.
181
191
type config struct {
182
- Type string `json:"type"`
183
- Audience string `json:"audience"`
184
- SubjectTokenType string `json:"subject_token_type"`
185
- TokenURL string `json:"token_url"`
186
- ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
187
- CredentialSource credentialSource `json:"credential_source"`
192
+ Type string `json:"type"`
193
+ Audience string `json:"audience"`
194
+ SubjectTokenType string `json:"subject_token_type"`
195
+ TokenURL string `json:"token_url"`
196
+ ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
197
+ ServiceAccountImpersonation serviceAccountImpersonationInfo `json:"service_account_impersonation,omitempty"`
198
+ CredentialSource credentialSource `json:"credential_source"`
199
+ }
200
+
201
+ type serviceAccountImpersonationInfo struct {
202
+ TokenLifetimeSeconds int `json:"token_lifetime_seconds,omitempty"`
188
203
}
189
204
190
205
type credentialSource struct {
191
206
File string `json:"file,omitempty"`
192
207
URL string `json:"url,omitempty"`
193
208
Executable executableConfig `json:"executable,omitempty"`
194
209
EnvironmentID string `json:"environment_id,omitempty"`
195
- RegionURL string `json:"region_url"`
210
+ RegionURL string `json:"region_url,omitempty "`
196
211
RegionalCredVerificationURL string `json:"regional_cred_verification_url,omitempty"`
197
212
}
198
213
199
214
type executableConfig struct {
200
- Command string `json:"command"`
215
+ Command string `json:"command,omitempty "`
201
216
TimeoutMillis int `json:"timeout_millis,omitempty"`
202
217
OutputFile string `json:"output_file,omitempty"`
203
218
}
@@ -380,3 +395,58 @@ echo "{\"success\":true,\"version\":1,\"expiration_time\":%v,\"token_type\":\"ur
380
395
},
381
396
})
382
397
}
398
+
399
+ func TestConfigurableTokenLifetime (t * testing.T ) {
400
+ if testing .Short () {
401
+ t .Skip ("skipping integration test" )
402
+ }
403
+
404
+ // Set up Token as a file
405
+ tokenFile , err := ioutil .TempFile ("" , "token.txt" )
406
+ if err != nil {
407
+ t .Fatalf ("Error creating token file:" )
408
+ }
409
+ defer os .Remove (tokenFile .Name ())
410
+
411
+ tokenFile .WriteString (oidcToken )
412
+ tokenFile .Close ()
413
+
414
+ const tokenLifetimeSeconds = 2800
415
+ const safetyBuffer = 5
416
+
417
+ writeConfig (t , config {
418
+ Type : "external_account" ,
419
+ Audience : oidcAudience ,
420
+ SubjectTokenType : "urn:ietf:params:oauth:token-type:jwt" ,
421
+ TokenURL : "https://sts.googleapis.com/v1/token" ,
422
+ ServiceAccountImpersonationURL : fmt .Sprintf ("https://iamcredentials.googleapis.com/v1/%s:generateAccessToken" , clientID ),
423
+ ServiceAccountImpersonation : serviceAccountImpersonationInfo {
424
+ TokenLifetimeSeconds : tokenLifetimeSeconds ,
425
+ },
426
+ CredentialSource : credentialSource {
427
+ File : tokenFile .Name (),
428
+ },
429
+ }, func (filename string ) {
430
+ b , err := ioutil .ReadFile (filename )
431
+ if err != nil {
432
+ t .Fatalf ("Coudn't read temp config file" )
433
+ }
434
+
435
+ creds , err := google .CredentialsFromJSON (context .Background (), b , "https://www.googleapis.com/auth/cloud-platform" )
436
+ if err != nil {
437
+ t .Fatalf ("Error retrieving credentials" )
438
+ }
439
+
440
+ token , err := creds .TokenSource .Token ()
441
+ if err != nil {
442
+ t .Fatalf ("Error getting token" )
443
+ }
444
+
445
+ now := time .Now ()
446
+ expiryMax := now .Add (tokenLifetimeSeconds * time .Second )
447
+ expiryMin := expiryMax .Add (- safetyBuffer * time .Second )
448
+ if token .Expiry .Before (expiryMin ) || token .Expiry .After (expiryMax ) {
449
+ t .Fatalf ("Expiry time not set correctly. Got %v, want %v" , token .Expiry , expiryMax )
450
+ }
451
+ })
452
+ }
0 commit comments