listUserExternalAuths lists all external auths available to a user and their auth links if they exist. @Summary Get user external auths @ID get-user-external-auths @Security CoderSessionToken @Produce json @Tags Git @Success 200 {object} codersdk.ExternalAuthLink @Router /api/v2/external-auth [get]
(rw http.ResponseWriter, r *http.Request)
| 347 | // @Success 200 {object} codersdk.ExternalAuthLink |
| 348 | // @Router /api/v2/external-auth [get] |
| 349 | func (api *API) listUserExternalAuths(rw http.ResponseWriter, r *http.Request) { |
| 350 | ctx := r.Context() |
| 351 | key := httpmw.APIKey(r) |
| 352 | |
| 353 | links, err := api.Database.GetExternalAuthLinksByUserID(ctx, key.UserID) |
| 354 | if err != nil { |
| 355 | if httpapi.Is404Error(err) { |
| 356 | httpapi.ResourceNotFound(rw) |
| 357 | return |
| 358 | } |
| 359 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 360 | Message: "Internal error fetching user's external auths.", |
| 361 | Detail: err.Error(), |
| 362 | }) |
| 363 | return |
| 364 | } |
| 365 | |
| 366 | // This process of authenticating each external link increases the |
| 367 | // response time. However, it is necessary to more correctly debug |
| 368 | // authentication issues. |
| 369 | // We can do this in parallel if we want to speed it up. |
| 370 | configs := make(map[string]*externalauth.Config) |
| 371 | for _, cfg := range api.ExternalAuthConfigs { |
| 372 | configs[cfg.ID] = cfg |
| 373 | } |
| 374 | // Check if the links are authenticated. |
| 375 | linkMeta := make(map[string]db2sdk.ExternalAuthMeta) |
| 376 | for i, link := range links { |
| 377 | if link.OAuthAccessToken != "" { |
| 378 | cfg, ok := configs[link.ProviderID] |
| 379 | if ok { |
| 380 | newLink, err := cfg.RefreshToken(ctx, api.Database, link) |
| 381 | meta := db2sdk.ExternalAuthMeta{ |
| 382 | Authenticated: err == nil, |
| 383 | } |
| 384 | if err != nil { |
| 385 | meta.ValidateError = err.Error() |
| 386 | } |
| 387 | linkMeta[link.ProviderID] = meta |
| 388 | |
| 389 | // Update the link if it was potentially refreshed. |
| 390 | if err == nil { |
| 391 | links[i] = newLink |
| 392 | } |
| 393 | } |
| 394 | } |
| 395 | } |
| 396 | |
| 397 | // Note: It would be really nice if we could cfg.Validate() the links and |
| 398 | // return their authenticated status. To do this, we would also have to |
| 399 | // refresh expired tokens too. For now, I do not want to cause the excess |
| 400 | // traffic on this request, so the user will have to do this with a separate |
| 401 | // call. |
| 402 | httpapi.Write(ctx, rw, http.StatusOK, codersdk.ListUserExternalAuthResponse{ |
| 403 | Providers: ExternalAuthConfigs(api.ExternalAuthConfigs), |
| 404 | Links: db2sdk.ExternalAuths(links, linkMeta), |
| 405 | }) |
| 406 | } |
nothing calls this directly
no test coverage detected