(rw http.ResponseWriter, r *http.Request)
| 6506 | } |
| 6507 | |
| 6508 | func (api *API) listUserAIProviderKeyConfigs(rw http.ResponseWriter, r *http.Request) { |
| 6509 | ctx := r.Context() |
| 6510 | targetUser := httpmw.UserParam(r) |
| 6511 | //nolint:gocritic // Users can list limited provider metadata to manage their own AI provider keys. |
| 6512 | metadataCtx := dbauthz.AsAIProviderMetadataReader(ctx) |
| 6513 | providers, err := api.Database.GetAIProviders(metadataCtx, database.GetAIProvidersParams{IncludeDisabled: true}) |
| 6514 | if err != nil { |
| 6515 | api.Logger.Error(ctx, "failed to list user AI provider configs", slog.Error(err), slog.F("user_id", targetUser.ID)) |
| 6516 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{Message: "Failed to list AI providers."}) |
| 6517 | return |
| 6518 | } |
| 6519 | keys, err := api.Database.GetUserAIProviderKeysByUserID(ctx, targetUser.ID) |
| 6520 | if err != nil { |
| 6521 | api.Logger.Error(ctx, "failed to list user AI provider keys", slog.Error(err), slog.F("user_id", targetUser.ID)) |
| 6522 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{Message: "Failed to list user AI provider keys."}) |
| 6523 | return |
| 6524 | } |
| 6525 | |
| 6526 | keysByProviderID := make(map[uuid.UUID]struct{}, len(keys)) |
| 6527 | for _, key := range keys { |
| 6528 | keysByProviderID[key.AIProviderID] = struct{}{} |
| 6529 | } |
| 6530 | |
| 6531 | visibleProviders := make([]database.AIProvider, 0, len(providers)) |
| 6532 | visibleProviderIDs := make([]uuid.UUID, 0, len(providers)) |
| 6533 | for _, provider := range providers { |
| 6534 | _, hasUserKey := keysByProviderID[provider.ID] |
| 6535 | if !provider.Enabled && !hasUserKey { |
| 6536 | continue |
| 6537 | } |
| 6538 | visibleProviders = append(visibleProviders, provider) |
| 6539 | visibleProviderIDs = append(visibleProviderIDs, provider.ID) |
| 6540 | } |
| 6541 | |
| 6542 | providerKeysByProviderID := make(map[uuid.UUID]struct{}, len(visibleProviderIDs)) |
| 6543 | if len(visibleProviderIDs) > 0 { |
| 6544 | providerKeyIDs, err := api.Database.GetAIProviderKeyPresence(metadataCtx, visibleProviderIDs) |
| 6545 | if err != nil { |
| 6546 | api.Logger.Error(ctx, "failed to list AI provider key presence", slog.Error(err), slog.F("user_id", targetUser.ID)) |
| 6547 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{Message: "Failed to list AI provider keys."}) |
| 6548 | return |
| 6549 | } |
| 6550 | for _, providerID := range providerKeyIDs { |
| 6551 | providerKeysByProviderID[providerID] = struct{}{} |
| 6552 | } |
| 6553 | } |
| 6554 | |
| 6555 | byokEnabled := api.DeploymentValues.AI.BridgeConfig.AllowBYOK.Value() |
| 6556 | configs := make([]codersdk.UserAIProviderKeyConfig, 0, len(visibleProviders)) |
| 6557 | for _, provider := range visibleProviders { |
| 6558 | _, hasUserKey := keysByProviderID[provider.ID] |
| 6559 | _, hasProviderKey := providerKeysByProviderID[provider.ID] |
| 6560 | configs = append(configs, codersdk.UserAIProviderKeyConfig{ |
| 6561 | Provider: convertAIProviderSummary(provider), |
| 6562 | HasUserAPIKey: hasUserKey, |
| 6563 | HasProviderAPIKey: hasProviderKey, |
| 6564 | BYOKEnabled: byokEnabled, |
| 6565 | }) |
nothing calls this directly
no test coverage detected