|
1 | 1 | package coderd_test |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "net/http" |
5 | 6 | "regexp" |
6 | 7 | "testing" |
7 | 8 |
|
8 | 9 | "github.com/golang-jwt/jwt/v4" |
9 | 10 | "github.com/stretchr/testify/require" |
| 11 | + "golang.org/x/xerrors" |
10 | 12 |
|
11 | 13 | "github.com/coder/coder/v2/coderd" |
12 | 14 | "github.com/coder/coder/v2/coderd/coderdtest" |
@@ -357,6 +359,40 @@ func TestUserOIDC(t *testing.T) { |
357 | 359 | runner.ForceRefresh(t, client, claims) |
358 | 360 | } |
359 | 361 | }) |
| 362 | + |
| 363 | + t.Run("FailedRefresh", func(t *testing.T) { |
| 364 | + t.Parallel() |
| 365 | + |
| 366 | + runner := setupOIDCTest(t, oidcTestConfig{ |
| 367 | + FakeOpts: []oidctest.FakeIDPOpt{ |
| 368 | + oidctest.WithRefreshHook(func(_ string) error { |
| 369 | + // Always "expired" refresh token. |
| 370 | + return xerrors.New("refresh token is expired") |
| 371 | + }), |
| 372 | + }, |
| 373 | + Config: func(cfg *coderd.OIDCConfig) { |
| 374 | + cfg.AllowSignups = true |
| 375 | + }, |
| 376 | + }) |
| 377 | + |
| 378 | + claims := jwt.MapClaims{ |
| 379 | + "email": "alice@coder.com", |
| 380 | + } |
| 381 | + // Login a new client that signs up |
| 382 | + client, resp := runner.Login(t, claims) |
| 383 | + require.Equal(t, http.StatusOK, resp.StatusCode) |
| 384 | + |
| 385 | + // Expire the token, cause a refresh |
| 386 | + runner.ExpireOauthToken(t, client) |
| 387 | + |
| 388 | + // This should fail because the oauth token refresh should fail. |
| 389 | + _, err := client.User(context.Background(), codersdk.Me) |
| 390 | + require.Error(t, err) |
| 391 | + var apiError *codersdk.Error |
| 392 | + require.ErrorAs(t, err, &apiError) |
| 393 | + require.Equal(t, http.StatusUnauthorized, apiError.StatusCode()) |
| 394 | + require.ErrorContains(t, apiError, "refresh") |
| 395 | + }) |
360 | 396 | }) |
361 | 397 | } |
362 | 398 |
|
@@ -576,14 +612,16 @@ type oidcTestRunner struct { |
576 | 612 | // ForceRefresh will use an authenticated codersdk.Client, and force their |
577 | 613 | // OIDC token to be expired and require a refresh. The refresh will use the claims provided. |
578 | 614 | // It just calls the /users/me endpoint to trigger the refresh. |
579 | | - ForceRefresh func(t *testing.T, client *codersdk.Client, idToken jwt.MapClaims) |
| 615 | + ForceRefresh func(t *testing.T, client *codersdk.Client, idToken jwt.MapClaims) |
| 616 | + ExpireOauthToken func(t *testing.T, client *codersdk.Client) |
580 | 617 | } |
581 | 618 |
|
582 | 619 | type oidcTestConfig struct { |
583 | 620 | Userinfo jwt.MapClaims |
584 | 621 |
|
585 | 622 | // Config allows modifying the Coderd OIDC configuration. |
586 | | - Config func(cfg *coderd.OIDCConfig) |
| 623 | + Config func(cfg *coderd.OIDCConfig) |
| 624 | + FakeOpts []oidctest.FakeIDPOpt |
587 | 625 | } |
588 | 626 |
|
589 | 627 | func (r *oidcTestRunner) AssertRoles(t *testing.T, userIdent string, roles []string) { |
@@ -633,10 +671,12 @@ func setupOIDCTest(t *testing.T, settings oidcTestConfig) *oidcTestRunner { |
633 | 671 | t.Helper() |
634 | 672 |
|
635 | 673 | fake := oidctest.NewFakeIDP(t, |
636 | | - oidctest.WithStaticUserInfo(settings.Userinfo), |
637 | | - oidctest.WithLogging(t, nil), |
638 | | - // Run fake IDP on a real webserver |
639 | | - oidctest.WithServing(), |
| 674 | + append([]oidctest.FakeIDPOpt{ |
| 675 | + oidctest.WithStaticUserInfo(settings.Userinfo), |
| 676 | + oidctest.WithLogging(t, nil), |
| 677 | + // Run fake IDP on a real webserver |
| 678 | + oidctest.WithServing(), |
| 679 | + }, settings.FakeOpts...)..., |
640 | 680 | ) |
641 | 681 |
|
642 | 682 | ctx := testutil.Context(t, testutil.WaitMedium) |
@@ -665,5 +705,8 @@ func setupOIDCTest(t *testing.T, settings oidcTestConfig) *oidcTestRunner { |
665 | 705 | ForceRefresh: func(t *testing.T, client *codersdk.Client, idToken jwt.MapClaims) { |
666 | 706 | helper.ForceRefresh(t, api.Database, client, idToken) |
667 | 707 | }, |
| 708 | + ExpireOauthToken: func(t *testing.T, client *codersdk.Client) { |
| 709 | + helper.ExpireOauthToken(t, api.Database, client) |
| 710 | + }, |
668 | 711 | } |
669 | 712 | } |
0 commit comments