6
6
"errors"
7
7
"fmt"
8
8
"net/http"
9
+ "net/mail"
9
10
"strconv"
10
11
"strings"
11
12
@@ -219,12 +220,25 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
219
220
})
220
221
return
221
222
}
223
+ usernameRaw , ok := claims ["preferred_username" ]
224
+ var username string
225
+ if ok {
226
+ username , _ = usernameRaw .(string )
227
+ }
222
228
emailRaw , ok := claims ["email" ]
223
229
if ! ok {
224
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
225
- Message : "No email found in OIDC payload!" ,
226
- })
227
- return
230
+ // Email is an optional claim in OIDC and
231
+ // instead the email is frequently sent in
232
+ // "preferred_username". See:
233
+ // https://github.com/coder/coder/issues/4472
234
+ _ , err = mail .ParseAddress (username )
235
+ if err != nil {
236
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
237
+ Message : "No email found in OIDC payload!" ,
238
+ })
239
+ return
240
+ }
241
+ emailRaw = username
228
242
}
229
243
email , ok := emailRaw .(string )
230
244
if ! ok {
@@ -243,11 +257,6 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
243
257
return
244
258
}
245
259
}
246
- usernameRaw , ok := claims ["preferred_username" ]
247
- var username string
248
- if ok {
249
- username , _ = usernameRaw .(string )
250
- }
251
260
// The username is a required property in Coder. We make a best-effort
252
261
// attempt at using what the claims provide, but if that fails we will
253
262
// generate a random username.
0 commit comments