From 2ebd0ec6c5564e30f9e4b4039af14457f9ddf1ae Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 6 Jul 2023 16:46:22 -0400 Subject: [PATCH] fix: resolve nil pointer dereference on missing oauth config (#8352) --- coderd/httpmw/apikey.go | 7 +++++++ coderd/httpmw/apikey_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/coderd/httpmw/apikey.go b/coderd/httpmw/apikey.go index 509ce4a82a..e103ddc085 100644 --- a/coderd/httpmw/apikey.go +++ b/coderd/httpmw/apikey.go @@ -237,6 +237,13 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon } // Check if the OAuth token is expired if link.OAuthExpiry.Before(now) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" { + if cfg.OAuth2Configs == nil { + return write(http.StatusInternalServerError, codersdk.Response{ + Message: internalErrorMessage, + Detail: fmt.Sprintf("Unable to refresh OAuth token for login type %q. "+ + "No OAuth2Configs provided. Contact an administrator to configure this login type.", key.LoginType), + }) + } var oauthConfig OAuth2Config switch key.LoginType { case database.LoginTypeGithub: diff --git a/coderd/httpmw/apikey_test.go b/coderd/httpmw/apikey_test.go index 0c2e834f75..b4b7bb01f8 100644 --- a/coderd/httpmw/apikey_test.go +++ b/coderd/httpmw/apikey_test.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha256" "fmt" + "io" "net" "net/http" "net/http/httptest" @@ -595,4 +596,39 @@ func TestAPIKey(t *testing.T) { require.Equal(t, sentAPIKey.ExpiresAt, gotAPIKey.ExpiresAt) require.Equal(t, sentAPIKey.LoginType, gotAPIKey.LoginType) }) + + t.Run("MissongConfig", func(t *testing.T) { + t.Parallel() + var ( + db = dbfake.New() + user = dbgen.User(t, db, database.User{}) + _, token = dbgen.APIKey(t, db, database.APIKey{ + UserID: user.ID, + LastUsed: database.Now(), + ExpiresAt: database.Now().AddDate(0, 0, 1), + LoginType: database.LoginTypeOIDC, + }) + _ = dbgen.UserLink(t, db, database.UserLink{ + UserID: user.ID, + LoginType: database.LoginTypeOIDC, + OAuthRefreshToken: "random", + // expired + OAuthExpiry: time.Now().Add(time.Hour * -1), + }) + + r = httptest.NewRequest("GET", "/", nil) + rw = httptest.NewRecorder() + ) + r.Header.Set(codersdk.SessionTokenHeader, token) + + httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{ + DB: db, + RedirectToLogin: false, + })(successHandler).ServeHTTP(rw, r) + res := rw.Result() + defer res.Body.Close() + require.Equal(t, http.StatusInternalServerError, res.StatusCode) + out, _ := io.ReadAll(res.Body) + require.Contains(t, string(out), "Unable to refresh") + }) }