@@ -472,7 +472,7 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
472
472
})
473
473
})
474
474
475
- t .Run ("CORS " ,func (t * testing.T ) {
475
+ t .Run ("WorkspaceApplicationCORS " ,func (t * testing.T ) {
476
476
t .Parallel ()
477
477
478
478
// Set up test headers that should be returned by the app
@@ -481,108 +481,118 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) {
481
481
"Access-Control-Allow-Methods" : []string {"GET, POST, OPTIONS" },
482
482
}
483
483
484
- t .Run ("UnauthenticatedPassthruRejected" ,func (t * testing.T ) {
485
- t .Parallel ()
486
-
487
- ctx := testutil .Context (t ,testutil .WaitLong )
488
-
489
- appDetails := setupProxyTest (t ,& DeploymentOptions {
490
- headers :testHeaders ,
491
- })
492
-
493
- // Given: an unauthenticated client
494
- client := appDetails .AppClient (t )
495
- client .SetSessionToken ("" )
496
-
497
- // When: a request is made to an authenticated app with passthru CORS behavior
498
- resp ,err := requestWithRetries (ctx ,t ,client ,http .MethodGet ,appDetails .SubdomainAppURL (appDetails .Apps .AuthenticatedCORSPassthru ).String (),nil )
499
- require .NoError (t ,err )
500
- defer resp .Body .Close ()
501
-
502
- // Then: the request is redirected to login because even though CORS is passthru,
503
- // the request must still be authenticated first
504
- require .Equal (t ,http .StatusSeeOther ,resp .StatusCode )
505
- gotLocation ,err := resp .Location ()
506
- require .NoError (t ,err )
507
- require .Equal (t ,appDetails .SDKClient .URL .Host ,gotLocation .Host )
508
- require .Equal (t ,"/api/v2/applications/auth-redirect" ,gotLocation .Path )
509
- })
510
-
511
- t .Run ("AuthenticatedPassthruOK" ,func (t * testing.T ) {
512
- t .Parallel ()
513
-
514
- ctx := testutil .Context (t ,testutil .WaitLong )
515
-
516
- appDetails := setupProxyTest (t ,& DeploymentOptions {
517
- headers :testHeaders ,
518
- })
519
-
520
- userClient ,_ := coderdtest .CreateAnotherUser (t ,appDetails .SDKClient ,appDetails .FirstUser .OrganizationID ,rbac .RoleMember ())
521
- userAppClient := appDetails .AppClient (t )
522
- userAppClient .SetSessionToken (userClient .SessionToken ())
523
-
524
- // Given: an authenticated app with passthru CORS behavior
525
- resp ,err := requestWithRetries (ctx ,t ,userAppClient ,http .MethodGet ,appDetails .SubdomainAppURL (appDetails .Apps .AuthenticatedCORSPassthru ).String (),nil )
526
- require .NoError (t ,err )
527
- defer resp .Body .Close ()
528
- require .Equal (t ,http .StatusOK ,resp .StatusCode )
529
-
530
- // Check CORS headers are passed through
531
- require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Origin" ),resp .Header .Get ("Access-Control-Allow-Origin" ))
532
- require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Methods" ),resp .Header .Get ("Access-Control-Allow-Methods" ))
484
+ appDetails := setupProxyTest (t ,& DeploymentOptions {
485
+ headers :testHeaders ,
533
486
})
534
487
535
- t .Run ("UnauthenticatedPublicPassthruOK" ,func (t * testing.T ) {
536
- t .Parallel ()
488
+ unauthenticatedClient := func (t * testing.T ,appDetails * Details )* codersdk.Client {
489
+ c := appDetails .AppClient (t )
490
+ c .SetSessionToken ("" )
491
+ return c
492
+ }
537
493
538
- ctx := testutil .Context (t ,testutil .WaitLong )
494
+ authenticatedClient := func (t * testing.T ,appDetails * Details )* codersdk.Client {
495
+ uc ,_ := coderdtest .CreateAnotherUser (t ,appDetails .SDKClient ,appDetails .FirstUser .OrganizationID ,rbac .RoleMember ())
496
+ c := appDetails .AppClient (t )
497
+ c .SetSessionToken (uc .SessionToken ())
498
+ return c
499
+ }
539
500
540
- appDetails := setupProxyTest ( t , & DeploymentOptions {
541
- headers : testHeaders ,
542
- })
501
+ ownerClient := func ( t * testing. T , appDetails * Details ) * codersdk. Client {
502
+ return appDetails . SDKClient
503
+ }
543
504
544
- // Given: an unauthenticated client
545
- client := appDetails .AppClient (t )
546
- client .SetSessionToken ("" )
505
+ tests := []struct {
506
+ name string
507
+ app App
508
+ client func (t * testing.T ,appDetails * Details )* codersdk.Client
509
+ expectedStatusCode int
510
+ expectedCORSHeaders bool
511
+ }{
512
+ // Public
513
+ {
514
+ name :"Default/Public" ,
515
+ app :appDetails .Apps .PublicCORSDefault ,
516
+ client :unauthenticatedClient ,
517
+ expectedStatusCode :http .StatusOK ,
518
+ expectedCORSHeaders :false ,
519
+ },
520
+ {
521
+ name :"Passthru/Public" ,
522
+ app :appDetails .Apps .PublicCORSPassthru ,
523
+ client :unauthenticatedClient ,
524
+ expectedStatusCode :http .StatusOK ,
525
+ expectedCORSHeaders :true ,
526
+ },
527
+ // Authenticated
528
+ {
529
+ name :"Default/Authenticated" ,
530
+ app :appDetails .Apps .AuthenticatedCORSDefault ,
531
+ expectedCORSHeaders :false ,
532
+ client :authenticatedClient ,
533
+ expectedStatusCode :http .StatusOK ,
534
+ },
535
+ {
536
+ name :"Passthru/Authenticated" ,
537
+ app :appDetails .Apps .AuthenticatedCORSPassthru ,
538
+ expectedCORSHeaders :true ,
539
+ client :authenticatedClient ,
540
+ expectedStatusCode :http .StatusOK ,
541
+ },
542
+ {
543
+ // The CORS behavior will not affect unauthenticated requests.
544
+ // The request will be redirected to the login page.
545
+ name :"Passthru/Unauthenticated" ,
546
+ app :appDetails .Apps .AuthenticatedCORSPassthru ,
547
+ expectedCORSHeaders :false ,
548
+ client :unauthenticatedClient ,
549
+ expectedStatusCode :http .StatusSeeOther ,
550
+ },
551
+ // Owner
552
+ {
553
+ name :"Default/Owner" ,
554
+ app :appDetails .Apps .AuthenticatedCORSDefault ,
555
+ expectedCORSHeaders :false ,
556
+ client :ownerClient ,
557
+ expectedStatusCode :http .StatusOK ,
558
+ },
559
+ {
560
+ name :"Passthru/Owner" ,
561
+ app :appDetails .Apps .AuthenticatedCORSPassthru ,
562
+ expectedCORSHeaders :true ,
563
+ client :ownerClient ,
564
+ expectedStatusCode :http .StatusOK ,
565
+ },
566
+ }
547
567
548
- // When: a request is made to a public app with passthru CORS behavior
549
- resp ,err := requestWithRetries (ctx ,t ,client ,http .MethodGet ,appDetails .SubdomainAppURL (appDetails .Apps .PublicCORSPassthru ).String (),nil )
550
- require .NoError (t ,err )
551
- defer resp .Body .Close ()
568
+ for _ ,tc := range tests {
569
+ t .Run (tc .name ,func (t * testing.T ) {
570
+ t .Parallel ()
552
571
553
- // Then: the request succeeds because the app is public
554
- require .Equal (t ,http .StatusOK ,resp .StatusCode )
572
+ ctx := testutil .Context (t ,testutil .WaitLong )
555
573
556
- // Check CORS headers are passed through
557
- require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Origin" ),resp .Header .Get ("Access-Control-Allow-Origin" ))
558
- require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Methods" ),resp .Header .Get ("Access-Control-Allow-Methods" ))
559
- })
574
+ // Given: a client
575
+ client := tc .client (t ,appDetails )
560
576
561
- t .Run ("AuthenticatedPublicPassthruOK" ,func (t * testing.T ) {
562
- t .Parallel ()
577
+ // When: a request is made to an authenticated app with a specified CORS behavior
578
+ resp ,err := requestWithRetries (ctx ,t ,client ,http .MethodGet ,appDetails .SubdomainAppURL (tc .app ).String (),nil )
579
+ require .NoError (t ,err )
580
+ defer resp .Body .Close ()
563
581
564
- ctx := testutil .Context (t ,testutil .WaitLong )
582
+ // Then: the request must match expectations
583
+ require .Equal (t ,tc .expectedStatusCode ,resp .StatusCode )
584
+ require .NoError (t ,err )
565
585
566
- appDetails := setupProxyTest (t ,& DeploymentOptions {
567
- headers :testHeaders ,
586
+ // Then: the CORS headers must match expectations
587
+ if tc .expectedCORSHeaders {
588
+ require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Origin" ),resp .Header .Get ("Access-Control-Allow-Origin" ))
589
+ require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Methods" ),resp .Header .Get ("Access-Control-Allow-Methods" ))
590
+ }else {
591
+ require .Empty (t ,resp .Header .Get ("Access-Control-Allow-Origin" ))
592
+ require .Empty (t ,resp .Header .Get ("Access-Control-Allow-Methods" ))
593
+ }
568
594
})
569
-
570
- userClient ,_ := coderdtest .CreateAnotherUser (t ,appDetails .SDKClient ,appDetails .FirstUser .OrganizationID ,rbac .RoleMember ())
571
- userAppClient := appDetails .AppClient (t )
572
- userAppClient .SetSessionToken (userClient .SessionToken ())
573
-
574
- // Given: an authenticated client accessing a public app with passthru CORS behavior
575
- resp ,err := requestWithRetries (ctx ,t ,userAppClient ,http .MethodGet ,appDetails .SubdomainAppURL (appDetails .Apps .PublicCORSPassthru ).String (),nil )
576
- require .NoError (t ,err )
577
- defer resp .Body .Close ()
578
-
579
- // Then: the request succeeds because the app is public
580
- require .Equal (t ,http .StatusOK ,resp .StatusCode )
581
-
582
- // Check CORS headers are passed through
583
- require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Origin" ),resp .Header .Get ("Access-Control-Allow-Origin" ))
584
- require .Equal (t ,testHeaders .Get ("Access-Control-Allow-Methods" ),resp .Header .Get ("Access-Control-Allow-Methods" ))
585
- })
595
+ }
586
596
})
587
597
588
598
t .Run ("WorkspaceApplicationAuth" ,func (t * testing.T ) {