44
44
var defaultTestOpts = []option.ClientOption {
45
45
option .WithCredentialsFile ("../testdata/service_account.json" ),
46
46
}
47
+ var testClock = & mockClock {now : time .Now ()}
47
48
48
49
func TestMain (m * testing.M ) {
49
50
var (
@@ -74,6 +75,7 @@ func TestMain(m *testing.M) {
74
75
75
76
ks = & fileKeySource {FilePath : "../testdata/public_certs.json" }
76
77
}
78
+
77
79
client , err = NewClient (ctx , & internal.AuthConfig {
78
80
Creds : creds ,
79
81
Opts : opts ,
@@ -83,6 +85,7 @@ func TestMain(m *testing.M) {
83
85
log .Fatalln (err )
84
86
}
85
87
client .keySource = ks
88
+ client .clock = testClock
86
89
87
90
testGetUserResponse , err = ioutil .ReadFile ("../testdata/get_user.json" )
88
91
if err != nil {
@@ -289,6 +292,35 @@ func TestVerifyIDToken(t *testing.T) {
289
292
}
290
293
}
291
294
295
+ func TestVerifyIDTokenClockSkew (t * testing.T ) {
296
+ now := testClock .Now ().Unix ()
297
+ cases := []struct {
298
+ name string
299
+ token string
300
+ }{
301
+ {"FutureToken" , getIDToken (mockIDTokenPayload {"iat" : now + clockSkewSeconds - 1 })},
302
+ {"ExpiredToken" , getIDToken (mockIDTokenPayload {
303
+ "iat" : now - 1000 ,
304
+ "exp" : now - clockSkewSeconds + 1 ,
305
+ })},
306
+ }
307
+
308
+ for _ , tc := range cases {
309
+ t .Run (tc .name , func (t * testing.T ) {
310
+ ft , err := client .VerifyIDToken (ctx , tc .token )
311
+ if err != nil {
312
+ t .Errorf ("VerifyIDToken(%q) = (%q, %v); want = (token, nil)" , tc .name , ft , err )
313
+ }
314
+ if ft .Claims ["admin" ] != true {
315
+ t .Errorf ("Claims['admin'] = %v; want = true" , ft .Claims ["admin" ])
316
+ }
317
+ if ft .UID != ft .Subject {
318
+ t .Errorf ("UID = %q; Sub = %q; want UID = Sub" , ft .UID , ft .Subject )
319
+ }
320
+ })
321
+ }
322
+ }
323
+
292
324
func TestVerifyIDTokenInvalidSignature (t * testing.T ) {
293
325
parts := strings .Split (testIDToken , "." )
294
326
token := fmt .Sprintf ("%s:%s:invalidsignature" , parts [0 ], parts [1 ])
@@ -298,7 +330,7 @@ func TestVerifyIDTokenInvalidSignature(t *testing.T) {
298
330
}
299
331
300
332
func TestVerifyIDTokenError (t * testing.T ) {
301
- now := time .Now ().Unix ()
333
+ now := testClock .Now ().Unix ()
302
334
cases := []struct {
303
335
name string
304
336
token string
@@ -310,10 +342,10 @@ func TestVerifyIDTokenError(t *testing.T) {
310
342
{"EmptySubject" , getIDToken (mockIDTokenPayload {"sub" : "" })},
311
343
{"IntSubject" , getIDToken (mockIDTokenPayload {"sub" : 10 })},
312
344
{"LongSubject" , getIDToken (mockIDTokenPayload {"sub" : strings .Repeat ("a" , 129 )})},
313
- {"FutureToken" , getIDToken (mockIDTokenPayload {"iat" : now + 1000 })},
345
+ {"FutureToken" , getIDToken (mockIDTokenPayload {"iat" : now + clockSkewSeconds + 1 })},
314
346
{"ExpiredToken" , getIDToken (mockIDTokenPayload {
315
347
"iat" : now - 1000 ,
316
- "exp" : now - 100 ,
348
+ "exp" : now - clockSkewSeconds - 1 ,
317
349
})},
318
350
{"EmptyToken" , "" },
319
351
{"BadFormatToken" , "foobar" },
@@ -419,6 +451,14 @@ func verifyCustomToken(ctx context.Context, token string, expected map[string]in
419
451
t .Errorf ("Subject: %q; want: %q" , payload .Sub , email )
420
452
}
421
453
454
+ now := testClock .Now ().Unix ()
455
+ if payload .Exp != now + 3600 {
456
+ t .Errorf ("Exp: %d; want: %d" , payload .Exp , now + 3600 )
457
+ }
458
+ if payload .Iat != now {
459
+ t .Errorf ("Iat: %d; want: %d" , payload .Iat , now )
460
+ }
461
+
422
462
for k , v := range expected {
423
463
if payload .Claims [k ] != v {
424
464
t .Errorf ("Claim[%q]: %v; want: %v" , k , payload .Claims [k ], v )
@@ -434,8 +474,8 @@ func getIDTokenWithKid(kid string, p mockIDTokenPayload) string {
434
474
pCopy := mockIDTokenPayload {
435
475
"aud" : client .projectID ,
436
476
"iss" : "https://securetoken.google.com/" + client .projectID ,
437
- "iat" : time .Now ().Unix () - 100 ,
438
- "exp" : time .Now ().Unix () + 3600 ,
477
+ "iat" : testClock .Now ().Unix () - 100 ,
478
+ "exp" : testClock .Now ().Unix () + 3600 ,
439
479
"sub" : "1234567890" ,
440
480
"admin" : true ,
441
481
}
0 commit comments