(ctx context.Context, rw http.ResponseWriter, state httpmw.OAuth2State, logger slog.Logger)
| 1591 | } |
| 1592 | |
| 1593 | func (api *API) userInfoClaims(ctx context.Context, rw http.ResponseWriter, state httpmw.OAuth2State, logger slog.Logger) (userInfoClaims map[string]interface{}, ok bool) { |
| 1594 | userInfoClaims = make(map[string]interface{}) |
| 1595 | userInfo, err := api.OIDCConfig.Provider.UserInfo(ctx, oauth2.StaticTokenSource(state.Token)) |
| 1596 | switch { |
| 1597 | case err == nil: |
| 1598 | err = userInfo.Claims(&userInfoClaims) |
| 1599 | if err != nil { |
| 1600 | logger.Error(ctx, "oauth2: unable to unmarshal user info claims", slog.Error(err)) |
| 1601 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 1602 | Message: "Failed to unmarshal user info claims.", |
| 1603 | Detail: err.Error(), |
| 1604 | }) |
| 1605 | return nil, false |
| 1606 | } |
| 1607 | logger.Debug(ctx, "got oidc claims", |
| 1608 | slog.F("source", "userinfo"), |
| 1609 | slog.F("claim_fields", claimFields(userInfoClaims)), |
| 1610 | slog.F("blank", blankFields(userInfoClaims)), |
| 1611 | ) |
| 1612 | case !strings.Contains(err.Error(), "user info endpoint is not supported by this provider"): |
| 1613 | logger.Error(ctx, "oauth2: unable to obtain user information claims", slog.Error(err)) |
| 1614 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 1615 | Message: "Failed to obtain user information claims.", |
| 1616 | Detail: "The attempt to fetch claims via the UserInfo endpoint failed: " + err.Error(), |
| 1617 | }) |
| 1618 | return nil, false |
| 1619 | default: |
| 1620 | // The OIDC provider does not support the UserInfo endpoint. |
| 1621 | // This is not an error, but we should log it as it may mean |
| 1622 | // that some claims are missing. |
| 1623 | logger.Warn(ctx, "OIDC provider does not support the user info endpoint, ensure that all required claims are present in the id_token", |
| 1624 | slog.Error(err), |
| 1625 | ) |
| 1626 | } |
| 1627 | return userInfoClaims, true |
| 1628 | } |
| 1629 | |
| 1630 | // claimFields returns the sorted list of fields in the claims map. |
| 1631 | func claimFields(claims map[string]interface{}) []string { |
no test coverage detected