Skip to content

Commit 41c9b83

Browse files
committed
fix(coderd/httpmw): handle oauth config removed for existing auth
This commit fixes an edge case tied to unexpired oauth logins where the oauth provider is removed, the server restarted, and the users auth expiring after the fact. Refs #8351, #8352, #8390
1 parent 75f62dc commit 41c9b83

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

coderd/httpmw/apikey.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ type OAuth2Configs struct {
7777
OIDC OAuth2Config
7878
}
7979

80+
func (c *OAuth2Configs) IsZero() bool {
81+
if c == nil {
82+
return true
83+
}
84+
return c.Github == nil && c.OIDC == nil
85+
}
86+
8087
const (
8188
SignedOutErrorMessage = "You are signed out or your session has expired. Please sign in again to continue."
8289
internalErrorMessage = "An internal error occurred. Please try again or contact the system administrator."
@@ -237,13 +244,14 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon
237244
}
238245
// Check if the OAuth token is expired
239246
if link.OAuthExpiry.Before(now) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" {
240-
if cfg.OAuth2Configs == nil {
247+
if cfg.OAuth2Configs.IsZero() {
241248
return write(http.StatusInternalServerError, codersdk.Response{
242249
Message: internalErrorMessage,
243250
Detail: fmt.Sprintf("Unable to refresh OAuth token for login type %q. "+
244251
"No OAuth2Configs provided. Contact an administrator to configure this login type.", key.LoginType),
245252
})
246253
}
254+
247255
var oauthConfig OAuth2Config
248256
switch key.LoginType {
249257
case database.LoginTypeGithub:
@@ -256,6 +264,19 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon
256264
Detail: fmt.Sprintf("Unexpected authentication type %q.", key.LoginType),
257265
})
258266
}
267+
268+
// It's possible for cfg.OAuth2Configs to be non-nil, but still
269+
// missing this type. For example, if a user logged in with GitHub,
270+
// but the administrator later removed GitHub and replaced it with
271+
// OIDC.
272+
if oauthConfig == nil {
273+
return write(http.StatusInternalServerError, codersdk.Response{
274+
Message: internalErrorMessage,
275+
Detail: fmt.Sprintf("Unable to refresh OAuth token for login type %q. "+
276+
"OAuth2Config not provided. Contact an administrator to configure this login type.", key.LoginType),
277+
})
278+
}
279+
259280
// If it is, let's refresh it from the provided config
260281
token, err := oauthConfig.TokenSource(r.Context(), &oauth2.Token{
261282
AccessToken: link.OAuthAccessToken,

0 commit comments

Comments
 (0)