diff --git a/coderd/userauth.go b/coderd/userauth.go index 4dd67844cfb0b..7a18b9790df04 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net/http" + "net/mail" "strconv" "strings" @@ -219,12 +220,25 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) { }) return } + usernameRaw, ok := claims["preferred_username"] + var username string + if ok { + username, _ = usernameRaw.(string) + } emailRaw, ok := claims["email"] if !ok { - httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ - Message: "No email found in OIDC payload!", - }) - return + // Email is an optional claim in OIDC and + // instead the email is frequently sent in + // "preferred_username". See: + // https://github.com/coder/coder/issues/4472 + _, err = mail.ParseAddress(username) + if err != nil { + httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ + Message: "No email found in OIDC payload!", + }) + return + } + emailRaw = username } email, ok := emailRaw.(string) if !ok { @@ -243,11 +257,6 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) { return } } - usernameRaw, ok := claims["preferred_username"] - var username string - if ok { - username, _ = usernameRaw.(string) - } // The username is a required property in Coder. We make a best-effort // attempt at using what the claims provide, but if that fails we will // generate a random username. diff --git a/coderd/userauth_test.go b/coderd/userauth_test.go index 42ac974d4e5ee..9643351032a88 100644 --- a/coderd/userauth_test.go +++ b/coderd/userauth_test.go @@ -425,6 +425,15 @@ func TestUserOIDC(t *testing.T) { Username: "kyle", AllowSignups: true, StatusCode: http.StatusTemporaryRedirect, + }, { + // See: https://github.com/coder/coder/issues/4472 + Name: "UsernameIsEmail", + Claims: jwt.MapClaims{ + "preferred_username": "kyle@kwc.io", + }, + Username: "kyle", + AllowSignups: true, + StatusCode: http.StatusTemporaryRedirect, }, { Name: "WithPicture", Claims: jwt.MapClaims{
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: