20
20
using System . Threading . Tasks ;
21
21
using FirebaseAdmin . Auth . Tests ;
22
22
using FirebaseAdmin . Tests ;
23
- using FirebaseAdmin . Util ;
24
- using Google . Apis . Util ;
25
23
using Xunit ;
26
24
27
25
namespace FirebaseAdmin . Auth . Jwt . Tests
@@ -36,9 +34,6 @@ public class IdTokenVerificationTest
36
34
37
35
private const long ClockSkewSeconds = 5 * 60 ;
38
36
39
- private static readonly TestOptions WithIdTokenVerifier =
40
- new TestOptions { IdTokenVerifier = true } ;
41
-
42
37
[ Theory ]
43
38
[ MemberData ( nameof ( TestConfigs ) ) ]
44
39
public async Task ValidToken ( TestConfig config )
@@ -148,7 +143,7 @@ public async Task IncorrectAlgorithm(TestConfig config)
148
143
[ MemberData ( nameof ( TestConfigs ) ) ]
149
144
public async Task Expired ( TestConfig config )
150
145
{
151
- var expiryTime = TestConfig . Clock . UnixTimestamp ( ) - ( ClockSkewSeconds + 1 ) ;
146
+ var expiryTime = JwtTestUtils . Clock . UnixTimestamp ( ) - ( ClockSkewSeconds + 1 ) ;
152
147
var payload = new Dictionary < string , object > ( )
153
148
{
154
149
{ "exp" , expiryTime } ,
@@ -160,15 +155,15 @@ public async Task Expired(TestConfig config)
160
155
async ( ) => await auth . VerifyIdTokenAsync ( idToken ) ) ;
161
156
162
157
var expectedMessage = $ "Firebase ID token expired at { expiryTime } . "
163
- + $ "Expected to be greater than { TestConfig . Clock . UnixTimestamp ( ) } .";
158
+ + $ "Expected to be greater than { JwtTestUtils . Clock . UnixTimestamp ( ) } .";
164
159
this . CheckException ( exception , expectedMessage , AuthErrorCode . ExpiredIdToken ) ;
165
160
}
166
161
167
162
[ Theory ]
168
163
[ MemberData ( nameof ( TestConfigs ) ) ]
169
164
public async Task ExpiryTimeInAcceptableRange ( TestConfig config )
170
165
{
171
- var expiryTimeSeconds = TestConfig . Clock . UnixTimestamp ( ) - ClockSkewSeconds ;
166
+ var expiryTimeSeconds = JwtTestUtils . Clock . UnixTimestamp ( ) - ClockSkewSeconds ;
172
167
var payload = new Dictionary < string , object > ( )
173
168
{
174
169
{ "exp" , expiryTimeSeconds } ,
@@ -178,15 +173,14 @@ public async Task ExpiryTimeInAcceptableRange(TestConfig config)
178
173
179
174
var decoded = await auth . VerifyIdTokenAsync ( idToken ) ;
180
175
181
- Assert . Equal ( "testuser" , decoded . Uid ) ;
182
- Assert . Equal ( expiryTimeSeconds , decoded . ExpirationTimeSeconds ) ;
176
+ config . AssertFirebaseToken ( decoded , payload ) ;
183
177
}
184
178
185
179
[ Theory ]
186
180
[ MemberData ( nameof ( TestConfigs ) ) ]
187
181
public async Task InvalidIssuedAt ( TestConfig config )
188
182
{
189
- var issuedAt = TestConfig . Clock . UnixTimestamp ( ) + ( ClockSkewSeconds + 1 ) ;
183
+ var issuedAt = JwtTestUtils . Clock . UnixTimestamp ( ) + ( ClockSkewSeconds + 1 ) ;
190
184
var payload = new Dictionary < string , object > ( )
191
185
{
192
186
{ "iat" , issuedAt } ,
@@ -205,7 +199,7 @@ public async Task InvalidIssuedAt(TestConfig config)
205
199
[ MemberData ( nameof ( TestConfigs ) ) ]
206
200
public async Task IssuedAtInAcceptableRange ( TestConfig config )
207
201
{
208
- var issuedAtSeconds = TestConfig . Clock . UnixTimestamp ( ) + ClockSkewSeconds ;
202
+ var issuedAtSeconds = JwtTestUtils . Clock . UnixTimestamp ( ) + ClockSkewSeconds ;
209
203
var payload = new Dictionary < string , object > ( )
210
204
{
211
205
{ "iat" , issuedAtSeconds } ,
@@ -215,8 +209,7 @@ public async Task IssuedAtInAcceptableRange(TestConfig config)
215
209
216
210
var decoded = await auth . VerifyIdTokenAsync ( idToken ) ;
217
211
218
- Assert . Equal ( "testuser" , decoded . Uid ) ;
219
- Assert . Equal ( issuedAtSeconds , decoded . IssuedAtTimeSeconds ) ;
212
+ config . AssertFirebaseToken ( decoded , payload ) ;
220
213
}
221
214
222
215
[ Theory ]
@@ -260,6 +253,21 @@ public async Task CustomToken(TestConfig config)
260
253
this . CheckException ( exception , expectedMessage ) ;
261
254
}
262
255
256
+ [ Theory ]
257
+ [ MemberData ( nameof ( TestConfigs ) ) ]
258
+ public async Task SessionCookie ( TestConfig config )
259
+ {
260
+ var tokenBuilder = JwtTestUtils . SessionCookieBuilder ( config . TenantId ) ;
261
+ var sessionCookie = await tokenBuilder . CreateTokenAsync ( ) ;
262
+ var auth = config . CreateAuth ( ) ;
263
+
264
+ var exception = await Assert . ThrowsAsync < FirebaseAuthException > (
265
+ async ( ) => await auth . VerifyIdTokenAsync ( sessionCookie ) ) ;
266
+
267
+ var expectedMessage = "Firebase ID token has incorrect issuer (iss) claim." ;
268
+ this . CheckException ( exception , expectedMessage ) ;
269
+ }
270
+
263
271
[ Theory ]
264
272
[ MemberData ( nameof ( TestConfigs ) ) ]
265
273
public async Task InvalidAudience ( TestConfig config )
@@ -327,7 +335,7 @@ public async Task RevokedToken(TestConfig config)
327
335
""users"": [
328
336
{{
329
337
""localId"": ""testuser"",
330
- ""validSince"": { TestConfig . Clock . UnixTimestamp ( ) }
338
+ ""validSince"": { JwtTestUtils . Clock . UnixTimestamp ( ) }
331
339
}}
332
340
]
333
341
}}" ,
@@ -345,7 +353,7 @@ public async Task RevokedToken(TestConfig config)
345
353
var expectedMessage = "Firebase ID token has been revoked." ;
346
354
this . CheckException ( exception , expectedMessage , AuthErrorCode . RevokedIdToken ) ;
347
355
Assert . Equal ( 1 , handler . Calls ) ;
348
- config . AssertRequest ( "accounts:lookup" , handler . Requests [ 0 ] ) ;
356
+ JwtTestUtils . AssertRevocationCheckRequest ( config . TenantId , handler . Requests [ 0 ] . Url ) ;
349
357
}
350
358
351
359
[ Theory ]
@@ -369,7 +377,7 @@ public async Task ValidUnrevokedToken(TestConfig config)
369
377
370
378
Assert . Equal ( "testuser" , decoded . Uid ) ;
371
379
Assert . Equal ( 1 , handler . Calls ) ;
372
- config . AssertRequest ( "accounts:lookup" , handler . Requests [ 0 ] ) ;
380
+ JwtTestUtils . AssertRevocationCheckRequest ( config . TenantId , handler . Requests [ 0 ] . Url ) ;
373
381
}
374
382
375
383
[ Theory ]
@@ -395,7 +403,7 @@ public async Task CheckRevokedError(TestConfig config)
395
403
Assert . Null ( exception . InnerException ) ;
396
404
Assert . NotNull ( exception . HttpResponse ) ;
397
405
Assert . Equal ( 1 , handler . Calls ) ;
398
- config . AssertRequest ( "accounts:lookup" , handler . Requests [ 0 ] ) ;
406
+ JwtTestUtils . AssertRevocationCheckRequest ( config . TenantId , handler . Requests [ 0 ] . Url ) ;
399
407
}
400
408
401
409
[ Theory ]
@@ -434,30 +442,6 @@ public async Task TenantIdMismatch(TestConfig config)
434
442
this . CheckException ( exception , expectedMessage , AuthErrorCode . TenantIdMismatch ) ;
435
443
}
436
444
437
- // TODO(hkj): Remove the following method once the session cookie tests have been
438
- // refactored.
439
-
440
- /// <summary>
441
- /// Creates a mock ID token for testing purposes. By default the created token has an issue
442
- /// time 10 minutes ago, and an expirty time 50 minutes into the future. All header and
443
- /// payload claims can be overridden if needed.
444
- /// </summary>
445
- internal static async Task < string > CreateTestTokenAsync (
446
- Dictionary < string , object > headerOverrides = null ,
447
- Dictionary < string , object > payloadOverrides = null )
448
- {
449
- var tokenBuilder = new MockTokenBuilder
450
- {
451
- ProjectId = TestConfig . ProjectId ,
452
- Clock = TestConfig . Clock ,
453
- Signer = JwtTestUtils . DefaultSigner ,
454
- IssuerPrefix = "https://securetoken.google.com" ,
455
- Uid = "testuser" ,
456
- } ;
457
- return await tokenBuilder . CreateTokenAsync (
458
- headerOverrides , payloadOverrides ) ;
459
- }
460
-
461
445
private void CheckException (
462
446
FirebaseAuthException exception ,
463
447
string prefix ,
@@ -472,36 +456,17 @@ private void CheckException(
472
456
473
457
public class TestConfig
474
458
{
475
- internal const string ProjectId = "test-project" ;
476
-
477
- internal static readonly IClock Clock = new MockClock ( ) ;
478
-
479
- private readonly string tenantId ;
480
459
private readonly AuthBuilder authBuilder ;
481
460
private readonly MockTokenBuilder tokenBuilder ;
482
461
483
462
private TestConfig ( string tenantId = null )
484
463
{
485
- this . tenantId = tenantId ;
486
- this . authBuilder = new AuthBuilder
487
- {
488
- ProjectId = ProjectId ,
489
- Clock = Clock ,
490
- KeySource = JwtTestUtils . DefaultKeySource ,
491
- RetryOptions = RetryOptions . NoBackOff ,
492
- TenantId = tenantId ,
493
- } ;
494
- this . tokenBuilder = new MockTokenBuilder
495
- {
496
- ProjectId = ProjectId ,
497
- Clock = Clock ,
498
- Signer = JwtTestUtils . DefaultSigner ,
499
- IssuerPrefix = "https://securetoken.google.com" ,
500
- Uid = "testuser" ,
501
- TenantId = this . tenantId ,
502
- } ;
464
+ this . tokenBuilder = JwtTestUtils . IdTokenBuilder ( tenantId ) ;
465
+ this . authBuilder = JwtTestUtils . AuthBuilderForTokenVerification ( tenantId ) ;
503
466
}
504
467
468
+ public string TenantId => this . authBuilder . TenantId ;
469
+
505
470
public static TestConfig ForFirebaseAuth ( )
506
471
{
507
472
return new TestConfig ( ) ;
@@ -534,14 +499,6 @@ public void AssertFirebaseToken(
534
499
{
535
500
this . tokenBuilder . AssertFirebaseToken ( token , expectedClaims ) ;
536
501
}
537
-
538
- internal void AssertRequest (
539
- string expectedSuffix , MockMessageHandler . IncomingRequest request )
540
- {
541
- var tenantInfo = this . tenantId != null ? $ "/tenants/{ this . tenantId } " : string . Empty ;
542
- var expectedPath = $ "/v1/projects/{ ProjectId } { tenantInfo } /{ expectedSuffix } ";
543
- Assert . Equal ( expectedPath , request . Url . PathAndQuery ) ;
544
- }
545
502
}
546
503
}
547
504
}
0 commit comments