Skip to content

Commit 398e8fd

Browse files
authored
fix(coderd/httpmw): handle oauth config removed for existing auth (#8420)
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 e508d9a commit 398e8fd

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

coderd/httpmw/apikey.go

+22-1
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)