diff --git a/extensions/vscode/src/views/homeView.ts b/extensions/vscode/src/views/homeView.ts index bf92a60c9..523ed6086 100644 --- a/extensions/vscode/src/views/homeView.ts +++ b/extensions/vscode/src/views/homeView.ts @@ -35,6 +35,7 @@ import { isPreContentRecordWithConfig, useApi, AllContentRecordTypes, + EnvironmentConfig, } from "src/api"; import { useBus } from "src/bus"; import { EventStream } from "src/events"; @@ -944,7 +945,16 @@ export class HomeViewProvider implements WebviewViewProvider, Disposable { } } - private inputSecretName = async () => { + private inputSecretName = async ( + environment: EnvironmentConfig | undefined, + ) => { + const existingKeys = new Set(); + if (environment) { + for (const secret in environment) { + existingKeys.add(secret); + } + } + return await window.showInputBox({ title: "Add a Secret", prompt: "Enter the name of the secret.", @@ -953,6 +963,9 @@ export class HomeViewProvider implements WebviewViewProvider, Disposable { if (value.length === 0) { return "Secret names cannot be empty."; } + if (existingKeys.has(value)) { + return "There is already an environment variable with this name. Secrets and environment variable names must be unique."; + } return; }, }); @@ -971,7 +984,9 @@ export class HomeViewProvider implements WebviewViewProvider, Disposable { return; } - const name = await this.inputSecretName(); + const name = await this.inputSecretName( + activeConfig.configuration.environment, + ); if (name === undefined) { // Cancelled by the user return; diff --git a/internal/config/config.go b/internal/config/config.go index ca3733c44..ebd31de99 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,6 +3,7 @@ package config // Copyright (C) 2023 by Posit Software, PBC. import ( + "errors" "fmt" "io" "strings" @@ -114,6 +115,13 @@ func (cfg *Config) AddSecret(secret string) error { return nil // Secret already exists, no need to add } } + // Check if the secret name already exists in the environment + for e := range cfg.Environment { + if e == secret { + return errors.New("secret name already exists in environment") + } + } + cfg.Secrets = append(cfg.Secrets, secret) return nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 0ce88dffa..92f5504f0 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -182,6 +182,14 @@ func (s *ConfigSuite) TestApplySecretActionAddNoDuplicates() { s.Equal([]string{"existingSecret1", "existingSecret2"}, cfg.Secrets) } +func (s *ConfigSuite) TestApplySecretActionAddExitingEnvVar() { + cfg := New() + cfg.Environment = map[string]string{"existingEnvVar": "value"} + cfg.Secrets = []string{} + err := cfg.AddSecret("existingEnvVar") + s.NotNil(err) +} + func (s *ConfigSuite) TestApplySecretActionRemove() { cfg := New() cfg.Secrets = []string{"secret1", "secret2"}