From 104a91647c3814c13cec8049970b59fe70753b6e Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Mon, 29 Apr 2024 21:18:13 +0800 Subject: [PATCH 01/23] fix: resolved cli offline mode get --- cli/packages/util/secrets.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 27f0636a9..c3690b83d 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -332,7 +332,7 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo return nil, err } - if loggedInUserDetails.LoginExpired { + if isConnected && loggedInUserDetails.LoginExpired { PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again") } From 877b9a409e8fcd765a039d8df3690e8240e44279 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 30 Apr 2024 21:00:34 +0800 Subject: [PATCH 02/23] adjustment: modified isConnected check to query linked infisical URL --- cli/packages/util/common.go | 6 ++++-- cli/packages/util/secrets.go | 23 ++++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/cli/packages/util/common.go b/cli/packages/util/common.go index 2b57383ef..42ee74c77 100644 --- a/cli/packages/util/common.go +++ b/cli/packages/util/common.go @@ -4,6 +4,8 @@ import ( "fmt" "net/http" "os" + + "github.com/Infisical/infisical-merge/packages/config" ) func GetHomeDir() (string, error) { @@ -21,7 +23,7 @@ func WriteToFile(fileName string, dataToWrite []byte, filePerm os.FileMode) erro return nil } -func CheckIsConnectedToInternet() (ok bool) { - _, err := http.Get("http://clients3.google.com/generate_204") +func CheckIsConnectedToInfisicalAPI() (ok bool) { + _, err := http.Get(fmt.Sprintf("%v/status", config.INFISICAL_URL)) return err == nil } diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index c3690b83d..0ca66cc4f 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -307,27 +307,28 @@ func FilterSecretsByTag(plainTextSecrets []models.SingleEnvironmentVariable, tag } func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) { - isConnected := CheckIsConnectedToInternet() var secretsToReturn []models.SingleEnvironmentVariable // var serviceTokenDetails api.GetServiceTokenDetailsResponse var errorToReturn error if params.InfisicalToken == "" && params.UniversalAuthAccessToken == "" { - if isConnected { - log.Debug().Msg("GetAllEnvironmentVariables: Connected to internet, checking logged in creds") - - if projectConfigFilePath == "" { - RequireLocalWorkspaceFile() - } else { - ValidateWorkspaceFile(projectConfigFilePath) - } - - RequireLogin() + if projectConfigFilePath == "" { + RequireLocalWorkspaceFile() + } else { + ValidateWorkspaceFile(projectConfigFilePath) } + RequireLogin() + log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") loggedInUserDetails, err := GetCurrentLoggedInUserDetails() + isConnected := CheckIsConnectedToInfisicalAPI() + + if isConnected { + log.Debug().Msg("GetAllEnvironmentVariables: Connected to Infisical instance, checking logged in creds") + } + if err != nil { return nil, err } From 772dd464f564f00eda605d765e81e4d082dc33cc Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 30 Apr 2024 21:11:29 +0800 Subject: [PATCH 03/23] test: added integration test for secrets get all and secrets get all without connection --- .../test-TestUserAuth_SecretsGetAll | 7 +++ ...estUserAuth_SecretsGetAllWithoutConnection | 8 ++++ cli/test/secrets_test.go | 44 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 cli/test/.snapshots/test-TestUserAuth_SecretsGetAll create mode 100644 cli/test/.snapshots/test-TestUserAuth_SecretsGetAllWithoutConnection diff --git a/cli/test/.snapshots/test-TestUserAuth_SecretsGetAll b/cli/test/.snapshots/test-TestUserAuth_SecretsGetAll new file mode 100644 index 000000000..260607e97 --- /dev/null +++ b/cli/test/.snapshots/test-TestUserAuth_SecretsGetAll @@ -0,0 +1,7 @@ +┌───────────────┬──────────────┬─────────────┐ +│ SECRET NAME │ SECRET VALUE │ SECRET TYPE │ +├───────────────┼──────────────┼─────────────┤ +│ TEST-SECRET-1 │ test-value-1 │ shared │ +│ TEST-SECRET-2 │ test-value-2 │ shared │ +│ TEST-SECRET-3 │ test-value-3 │ shared │ +└───────────────┴──────────────┴─────────────┘ diff --git a/cli/test/.snapshots/test-TestUserAuth_SecretsGetAllWithoutConnection b/cli/test/.snapshots/test-TestUserAuth_SecretsGetAllWithoutConnection new file mode 100644 index 000000000..c48627f73 --- /dev/null +++ b/cli/test/.snapshots/test-TestUserAuth_SecretsGetAllWithoutConnection @@ -0,0 +1,8 @@ +Warning: Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug +┌───────────────┬──────────────┬─────────────┐ +│ SECRET NAME │ SECRET VALUE │ SECRET TYPE │ +├───────────────┼──────────────┼─────────────┤ +│ TEST-SECRET-1 │ test-value-1 │ shared │ +│ TEST-SECRET-2 │ test-value-2 │ shared │ +│ TEST-SECRET-3 │ test-value-3 │ shared │ +└───────────────┴──────────────┴─────────────┘ diff --git a/cli/test/secrets_test.go b/cli/test/secrets_test.go index 453666406..b9c8fa85d 100644 --- a/cli/test/secrets_test.go +++ b/cli/test/secrets_test.go @@ -3,9 +3,11 @@ package tests import ( "testing" + "github.com/Infisical/infisical-merge/packages/util" "github.com/bradleyjkemp/cupaloy/v2" ) + func TestServiceToken_SecretsGetWithImportsAndRecursiveCmd(t *testing.T) { SetupCli(t) @@ -85,3 +87,45 @@ func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) { } } + +func TestUserAuth_SecretsGetAll(t *testing.T) { + SetupCli(t) + output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--include-imports=false", "--silent") + if err != nil { + t.Fatalf("error running CLI command: %v", err) + } + + // Use cupaloy to snapshot test the output + err = cupaloy.Snapshot(output) + if err != nil { + t.Fatalf("snapshot failed: %v", err) + } +} + +func TestUserAuth_SecretsGetAllWithoutConnection(t *testing.T) { + SetupCli(t) + + originalConfigFile, err := util.GetConfigFile() + if err != nil { + t.Fatalf("error getting config file") + } + newConfigFile := originalConfigFile + + // set it to a URL that will always be unreachable + newConfigFile.LoggedInUserDomain = "http://localhost:4999" + util.WriteConfigFile(&newConfigFile) + + // restore config file + defer util.WriteConfigFile(&originalConfigFile) + + output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--include-imports=false", "--silent") + if err != nil { + t.Fatalf("error running CLI command: %v", err) + } + + // Use cupaloy to snapshot test the output + err = cupaloy.Snapshot(output) + if err != nil { + t.Fatalf("snapshot failed: %v", err) + } +} \ No newline at end of file From 531fa634a26a47d3e19dcb39a0975dc8d7bda168 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 30 Apr 2024 22:02:22 +0800 Subject: [PATCH 04/23] feature: add logs for cli execution error --- cli/test/helper.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/test/helper.go b/cli/test/helper.go index 995367c4b..470473368 100644 --- a/cli/test/helper.go +++ b/cli/test/helper.go @@ -38,6 +38,7 @@ func ExecuteCliCommand(command string, args ...string) (string, error) { cmd := exec.Command(command, args...) output, err := cmd.CombinedOutput() if err != nil { + fmt.Println(fmt.Sprint(err) + ": " + string(output)) return strings.TrimSpace(string(output)), err } return strings.TrimSpace(string(output)), nil From 85f024c814cca3ef2939215cb6e3aa74cfb5a581 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 01:45:24 +0800 Subject: [PATCH 05/23] test: added scripting for user login --- cli/go.mod | 1 + cli/go.sum | 2 + ...stUserAuth_SecretsGetAllWithoutConnection} | 0 cli/test/helper.go | 4 + cli/test/login_test.go | 78 +++++++++++++++++++ cli/test/secrets_test.go | 9 ++- 6 files changed, 91 insertions(+), 3 deletions(-) rename cli/test/.snapshots/{test-TestUserAuth_SecretsGetAllWithoutConnection => test-testUserAuth_SecretsGetAllWithoutConnection} (100%) diff --git a/cli/go.mod b/cli/go.mod index 833745eff..52c737533 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -31,6 +31,7 @@ require ( github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect github.com/bradleyjkemp/cupaloy/v2 v2.8.0 // indirect github.com/chzyer/readline v1.5.1 // indirect + github.com/creack/pty v1.1.21 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect diff --git a/cli/go.sum b/cli/go.sum index 353579136..ff3030a9c 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -74,6 +74,8 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= +github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/cli/test/.snapshots/test-TestUserAuth_SecretsGetAllWithoutConnection b/cli/test/.snapshots/test-testUserAuth_SecretsGetAllWithoutConnection similarity index 100% rename from cli/test/.snapshots/test-TestUserAuth_SecretsGetAllWithoutConnection rename to cli/test/.snapshots/test-testUserAuth_SecretsGetAllWithoutConnection diff --git a/cli/test/helper.go b/cli/test/helper.go index 470473368..b773d138e 100644 --- a/cli/test/helper.go +++ b/cli/test/helper.go @@ -23,6 +23,8 @@ type Credentials struct { ServiceToken string ProjectID string EnvSlug string + UserEmail string + UserPassword string } var creds = Credentials{ @@ -32,6 +34,8 @@ var creds = Credentials{ ServiceToken: os.Getenv("CLI_TESTS_SERVICE_TOKEN"), ProjectID: os.Getenv("CLI_TESTS_PROJECT_ID"), EnvSlug: os.Getenv("CLI_TESTS_ENV_SLUG"), + UserEmail: os.Getenv("CLI_TESTS_USER_EMAIL"), + UserPassword: os.Getenv("CLI_TESTS_USER_PASSWORD"), } func ExecuteCliCommand(command string, args ...string) (string, error) { diff --git a/cli/test/login_test.go b/cli/test/login_test.go index 0f4591413..6857c00fb 100644 --- a/cli/test/login_test.go +++ b/cli/test/login_test.go @@ -1,11 +1,89 @@ package tests import ( + "fmt" + "os/exec" + "strings" "testing" + "github.com/creack/pty" "github.com/stretchr/testify/assert" ) +func UserLoginCmd(t *testing.T) { + SetupCli(t) + + // set vault to file because CI has no keyring + vaultCmd := exec.Command(FORMATTED_CLI_NAME, "vault", "set", "file") + _, err := vaultCmd.Output() + if err != nil { + t.Fatalf("error setting vault: %v", err) + } + + // Start programmatic interaction with CLI + c := exec.Command(FORMATTED_CLI_NAME, "login", "--interactive") + ptmx, err := pty.Start(c) + if err != nil { + t.Fatalf("error running CLI command: %v", err) + } + defer func() { _ = ptmx.Close() }() + + stepChan := make(chan int, 10) + + go func() { + buf := make([]byte, 1024) + step := -1 + for { + n, err := ptmx.Read(buf) + if n > 0 { + terminalOut := string(buf) + if strings.Contains(terminalOut, "Add a new account") && step < 0 { + step += 1 + stepChan <- step + } else if strings.Contains(terminalOut, "Infisical Cloud") && step < 1 { + step += 1; + stepChan <- step + } else if strings.Contains(terminalOut, "Email") && step < 2 { + step += 1; + stepChan <- step + } else if strings.Contains(terminalOut, "Password") && step < 3 { + step += 1; + stepChan <- step + } else if strings.Contains(terminalOut, "Infisical organization") && step < 4 { + step += 1; + stepChan <- step + } else if strings.Contains(terminalOut, "Enter passphrase") && step < 5 { + step += 1; + stepChan <- step + } + } + if err != nil { + close(stepChan) + return + } + fmt.Print(string(buf[:n])) + } + }() + + for i := range stepChan { + switch i { + case 0: + ptmx.Write([]byte("\n")) + case 1: + ptmx.Write([]byte("\n")) + case 2: + ptmx.Write([]byte(creds.UserEmail)) + ptmx.Write([]byte("\n")) + case 3: + ptmx.Write([]byte(creds.UserPassword)) + ptmx.Write([]byte("\n")) + case 4: + ptmx.Write([]byte("\n")) + } + } + +} + func MachineIdentityLoginCmd(t *testing.T) { SetupCli(t) diff --git a/cli/test/secrets_test.go b/cli/test/secrets_test.go index b9c8fa85d..294434f5f 100644 --- a/cli/test/secrets_test.go +++ b/cli/test/secrets_test.go @@ -90,6 +90,8 @@ func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) { func TestUserAuth_SecretsGetAll(t *testing.T) { SetupCli(t) + UserLoginCmd(t); + output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--include-imports=false", "--silent") if err != nil { t.Fatalf("error running CLI command: %v", err) @@ -100,11 +102,12 @@ func TestUserAuth_SecretsGetAll(t *testing.T) { if err != nil { t.Fatalf("snapshot failed: %v", err) } + + // intentionally invoked this here because it should directly follow secretsGetAll + testUserAuth_SecretsGetAllWithoutConnection(t) } -func TestUserAuth_SecretsGetAllWithoutConnection(t *testing.T) { - SetupCli(t) - +func testUserAuth_SecretsGetAllWithoutConnection(t *testing.T) { originalConfigFile, err := util.GetConfigFile() if err != nil { t.Fatalf("error getting config file") From 6640b55504abab40fecec9a3d3c1847508636a79 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 01:49:06 +0800 Subject: [PATCH 06/23] misc: added envs required for cli test of infisical login --- .github/workflows/run-cli-tests.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-cli-tests.yml b/.github/workflows/run-cli-tests.yml index e814f9143..f55581a0f 100644 --- a/.github/workflows/run-cli-tests.yml +++ b/.github/workflows/run-cli-tests.yml @@ -20,7 +20,12 @@ on: required: true CLI_TESTS_ENV_SLUG: required: true - + CLI_TESTS_USER_EMAIL: + required: true + CLI_TESTS_USER_PASSWORD: + required: true + INFISICAL_VAULT_FILE_PASSPHRASE: + required: true jobs: test: defaults: @@ -43,5 +48,8 @@ jobs: CLI_TESTS_SERVICE_TOKEN: ${{ secrets.CLI_TESTS_SERVICE_TOKEN }} CLI_TESTS_PROJECT_ID: ${{ secrets.CLI_TESTS_PROJECT_ID }} CLI_TESTS_ENV_SLUG: ${{ secrets.CLI_TESTS_ENV_SLUG }} + CLI_TESTS_USER_EMAIL: ${{ secrets.CLI_TESTS_USER_EMAIL }} + CLI_TESTS_USER_PASSWORD: ${{ secrets.CLI_TESTS_USER_PASSWORD }} + INFISICAL_VAULT_FILE_PASSPHRASE: ${{ secrets.INFISICAL_VAULT_FILE_PASSPHRASE }} run: go test -v -count=1 ./test From 4479e626c7f4f5c52c8c51c5835c8be5450676ff Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 01:56:10 +0800 Subject: [PATCH 07/23] adjustment: renamed cli vault file phrase env --- .github/workflows/run-cli-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-cli-tests.yml b/.github/workflows/run-cli-tests.yml index f55581a0f..f8e9d7797 100644 --- a/.github/workflows/run-cli-tests.yml +++ b/.github/workflows/run-cli-tests.yml @@ -24,7 +24,7 @@ on: required: true CLI_TESTS_USER_PASSWORD: required: true - INFISICAL_VAULT_FILE_PASSPHRASE: + CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE: required: true jobs: test: @@ -50,6 +50,6 @@ jobs: CLI_TESTS_ENV_SLUG: ${{ secrets.CLI_TESTS_ENV_SLUG }} CLI_TESTS_USER_EMAIL: ${{ secrets.CLI_TESTS_USER_EMAIL }} CLI_TESTS_USER_PASSWORD: ${{ secrets.CLI_TESTS_USER_PASSWORD }} - INFISICAL_VAULT_FILE_PASSPHRASE: ${{ secrets.INFISICAL_VAULT_FILE_PASSPHRASE }} + INFISICAL_VAULT_FILE_PASSPHRASE: ${{ secrets.CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE }} run: go test -v -count=1 ./test From 3897bd70fa107824f5c471d33a136f4747cb0159 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 11:08:58 +0800 Subject: [PATCH 08/23] adjustment: removed cli display for pty --- cli/test/login_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli/test/login_test.go b/cli/test/login_test.go index 6857c00fb..d376d05db 100644 --- a/cli/test/login_test.go +++ b/cli/test/login_test.go @@ -1,7 +1,6 @@ package tests import ( - "fmt" "os/exec" "strings" "testing" @@ -61,7 +60,6 @@ func UserLoginCmd(t *testing.T) { close(stepChan) return } - fmt.Print(string(buf[:n])) } }() From 505ccdf8eaa1e3d50a4898825ee1879d5597b66c Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 21:37:18 +0800 Subject: [PATCH 09/23] misc: added script for cli-tests env setup --- cli/.gitignore | 1 + cli/scripts/export_test_env.sh | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 cli/scripts/export_test_env.sh diff --git a/cli/.gitignore b/cli/.gitignore index 5fa3e39c5..8eb54d72b 100644 --- a/cli/.gitignore +++ b/cli/.gitignore @@ -1,3 +1,4 @@ .infisical.json dist/ agent-config.test.yaml +.test.env \ No newline at end of file diff --git a/cli/scripts/export_test_env.sh b/cli/scripts/export_test_env.sh new file mode 100644 index 000000000..08b5ad41b --- /dev/null +++ b/cli/scripts/export_test_env.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +TEST_ENV_FILE=".test.env" + +# Check if the .env file exists +if [ ! -f "$TEST_ENV_FILE" ]; then + echo "$TEST_ENV_FILE does not exist." + exit 1 +fi + +# Export the variables +while IFS='=' read -r key value +do + # Skip empty lines and lines starting with # + if [[ -z "$key" || "$key" =~ ^\# ]]; then + continue + fi + # Use eval to correctly handle values with spaces + eval export $key='$value' +done < "$TEST_ENV_FILE" + +echo "Test environment variables set." From a5ca96f2df59e2f2247bb32cfed24b2858931398 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 21:39:20 +0800 Subject: [PATCH 10/23] test: restructed setup and added scripting for infisical init --- cli/go.mod | 4 +-- cli/test/export_test.go | 7 ----- cli/test/helper.go | 6 ++-- cli/test/login_test.go | 53 ++++++++++++++++++++++++++++---- cli/test/main_test.go | 23 ++++++++++++++ cli/test/run_test.go | 12 -------- cli/test/secrets_by_name_test.go | 12 -------- cli/test/secrets_test.go | 10 ------ 8 files changed, 75 insertions(+), 52 deletions(-) create mode 100644 cli/test/main_test.go diff --git a/cli/go.mod b/cli/go.mod index 52c737533..6a1da8c6d 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -3,7 +3,9 @@ module github.com/Infisical/infisical-merge go 1.21 require ( + github.com/bradleyjkemp/cupaloy/v2 v2.8.0 github.com/charmbracelet/lipgloss v0.5.0 + github.com/creack/pty v1.1.21 github.com/denisbrodbeck/machineid v1.0.1 github.com/fatih/semgroup v1.2.0 github.com/gitleaks/go-gitdiff v0.8.0 @@ -29,9 +31,7 @@ require ( require ( github.com/alessio/shellescape v1.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect - github.com/bradleyjkemp/cupaloy/v2 v2.8.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/creack/pty v1.1.21 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect diff --git a/cli/test/export_test.go b/cli/test/export_test.go index 9a936871d..c44bf20af 100644 --- a/cli/test/export_test.go +++ b/cli/test/export_test.go @@ -8,7 +8,6 @@ import ( func TestUniversalAuth_ExportSecretsWithImports(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "export", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent") @@ -24,8 +23,6 @@ func TestUniversalAuth_ExportSecretsWithImports(t *testing.T) { } func TestServiceToken_ExportSecretsWithImports(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "export", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent") if err != nil { @@ -41,8 +38,6 @@ func TestServiceToken_ExportSecretsWithImports(t *testing.T) { func TestUniversalAuth_ExportSecretsWithoutImports(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "export", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent", "--include-imports=false") if err != nil { @@ -57,8 +52,6 @@ func TestUniversalAuth_ExportSecretsWithoutImports(t *testing.T) { } func TestServiceToken_ExportSecretsWithoutImports(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "export", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent", "--include-imports=false") if err != nil { diff --git a/cli/test/helper.go b/cli/test/helper.go index b773d138e..819f4c4c9 100644 --- a/cli/test/helper.go +++ b/cli/test/helper.go @@ -2,10 +2,10 @@ package tests import ( "fmt" + "log" "os" "os/exec" "strings" - "testing" ) const ( @@ -48,7 +48,7 @@ func ExecuteCliCommand(command string, args ...string) (string, error) { return strings.TrimSpace(string(output)), nil } -func SetupCli(t *testing.T) { +func SetupCli() { if creds.ClientID == "" || creds.ClientSecret == "" || creds.ServiceToken == "" || creds.ProjectID == "" || creds.EnvSlug == "" { panic("Missing required environment variables") @@ -62,7 +62,7 @@ func SetupCli(t *testing.T) { if !alreadyBuilt { if err := exec.Command("go", "build", "../.").Run(); err != nil { - t.Fatal(err) + log.Fatal(err) } } diff --git a/cli/test/login_test.go b/cli/test/login_test.go index d376d05db..2bc356855 100644 --- a/cli/test/login_test.go +++ b/cli/test/login_test.go @@ -1,6 +1,8 @@ package tests import ( + "fmt" + "log" "os/exec" "strings" "testing" @@ -9,21 +11,62 @@ import ( "github.com/stretchr/testify/assert" ) -func UserLoginCmd(t *testing.T) { - SetupCli(t) +func UserInitCmd() { + c := exec.Command(FORMATTED_CLI_NAME, "init") + ptmx, err := pty.Start(c) + if err != nil { + log.Fatalf("error running CLI command: %v", err) + } + defer func() { _ = ptmx.Close() }() + stepChan := make(chan int, 10) + + go func() { + buf := make([]byte, 1024) + step := -1 + for { + n, err := ptmx.Read(buf) + if n > 0 { + terminalOut := string(buf) + fmt.Println("Terminal out is", terminalOut) + if strings.Contains(terminalOut, "Which Infisical organization would you like to select a project from?") && step < 0 { + step += 1 + stepChan <- step + } else if strings.Contains(terminalOut, "Which of your Infisical projects would you like to connect this project to?") && step < 1 { + step += 1; + stepChan <- step + } + } + if err != nil { + close(stepChan) + return + } + } + }() + + for i := range stepChan { + switch i { + case 0: + ptmx.Write([]byte("\n")) + case 1: + ptmx.Write([]byte("\n")) + } + } +} + +func UserLoginCmd() { // set vault to file because CI has no keyring vaultCmd := exec.Command(FORMATTED_CLI_NAME, "vault", "set", "file") _, err := vaultCmd.Output() if err != nil { - t.Fatalf("error setting vault: %v", err) + log.Fatalf("error setting vault: %v", err) } // Start programmatic interaction with CLI c := exec.Command(FORMATTED_CLI_NAME, "login", "--interactive") ptmx, err := pty.Start(c) if err != nil { - t.Fatalf("error running CLI command: %v", err) + log.Fatalf("error running CLI command: %v", err) } defer func() { _ = ptmx.Close() }() @@ -83,8 +126,6 @@ func UserLoginCmd(t *testing.T) { } func MachineIdentityLoginCmd(t *testing.T) { - SetupCli(t) - if creds.UAAccessToken != "" { return } diff --git a/cli/test/main_test.go b/cli/test/main_test.go new file mode 100644 index 000000000..e14893aec --- /dev/null +++ b/cli/test/main_test.go @@ -0,0 +1,23 @@ +package tests + +import ( + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + // Setup + fmt.Println("Setting up CLI...") + SetupCli() + fmt.Println("Performing user login...") + UserLoginCmd() + fmt.Println("Performing infisical init...") + UserInitCmd() + + // Run the tests + code := m.Run() + + // Exit + os.Exit(code) +} diff --git a/cli/test/run_test.go b/cli/test/run_test.go index 808f4f14f..d2c6021cc 100644 --- a/cli/test/run_test.go +++ b/cli/test/run_test.go @@ -8,8 +8,6 @@ import ( ) func TestServiceToken_RunCmdRecursiveAndImports(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "run", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent", "--", "echo", "hello world") if err != nil { @@ -25,8 +23,6 @@ func TestServiceToken_RunCmdRecursiveAndImports(t *testing.T) { } } func TestServiceToken_RunCmdWithImports(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "run", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent", "--", "echo", "hello world") if err != nil { @@ -44,8 +40,6 @@ func TestServiceToken_RunCmdWithImports(t *testing.T) { func TestUniversalAuth_RunCmdRecursiveAndImports(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "run", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent", "--", "echo", "hello world") if err != nil { @@ -63,8 +57,6 @@ func TestUniversalAuth_RunCmdRecursiveAndImports(t *testing.T) { func TestUniversalAuth_RunCmdWithImports(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "run", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent", "--", "echo", "hello world") if err != nil { @@ -83,8 +75,6 @@ func TestUniversalAuth_RunCmdWithImports(t *testing.T) { func TestUniversalAuth_RunCmdWithoutImports(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "run", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent", "--include-imports=false", "--", "echo", "hello world") if err != nil { @@ -101,8 +91,6 @@ func TestUniversalAuth_RunCmdWithoutImports(t *testing.T) { } func TestServiceToken_RunCmdWithoutImports(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "run", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--silent", "--include-imports=false", "--", "echo", "hello world") if err != nil { diff --git a/cli/test/secrets_by_name_test.go b/cli/test/secrets_by_name_test.go index 440324e1a..26a8314bb 100644 --- a/cli/test/secrets_by_name_test.go +++ b/cli/test/secrets_by_name_test.go @@ -7,8 +7,6 @@ import ( ) func TestServiceToken_GetSecretsByNameRecursive(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "get", "TEST-SECRET-1", "TEST-SECRET-2", "FOLDER-SECRET-1", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { @@ -23,8 +21,6 @@ func TestServiceToken_GetSecretsByNameRecursive(t *testing.T) { } func TestServiceToken_GetSecretsByNameWithNotFoundSecret(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "get", "TEST-SECRET-1", "TEST-SECRET-2", "FOLDER-SECRET-1", "DOES-NOT-EXIST", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { @@ -39,8 +35,6 @@ func TestServiceToken_GetSecretsByNameWithNotFoundSecret(t *testing.T) { } func TestServiceToken_GetSecretsByNameWithImports(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "get", "TEST-SECRET-1", "STAGING-SECRET-2", "FOLDER-SECRET-1", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { @@ -56,8 +50,6 @@ func TestServiceToken_GetSecretsByNameWithImports(t *testing.T) { func TestUniversalAuth_GetSecretsByNameRecursive(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "get", "TEST-SECRET-1", "TEST-SECRET-2", "FOLDER-SECRET-1", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { @@ -73,8 +65,6 @@ func TestUniversalAuth_GetSecretsByNameRecursive(t *testing.T) { func TestUniversalAuth_GetSecretsByNameWithNotFoundSecret(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "get", "TEST-SECRET-1", "TEST-SECRET-2", "FOLDER-SECRET-1", "DOES-NOT-EXIST", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { @@ -90,8 +80,6 @@ func TestUniversalAuth_GetSecretsByNameWithNotFoundSecret(t *testing.T) { func TestUniversalAuth_GetSecretsByNameWithImports(t *testing.T) { MachineIdentityLoginCmd(t) - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "get", "TEST-SECRET-1", "STAGING-SECRET-2", "FOLDER-SECRET-1", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { diff --git a/cli/test/secrets_test.go b/cli/test/secrets_test.go index 294434f5f..7af64eab8 100644 --- a/cli/test/secrets_test.go +++ b/cli/test/secrets_test.go @@ -9,8 +9,6 @@ import ( func TestServiceToken_SecretsGetWithImportsAndRecursiveCmd(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") if err != nil { @@ -25,8 +23,6 @@ func TestServiceToken_SecretsGetWithImportsAndRecursiveCmd(t *testing.T) { } func TestServiceToken_SecretsGetWithoutImportsAndWithoutRecursiveCmd(t *testing.T) { - SetupCli(t) - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--token", creds.ServiceToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--include-imports=false", "--silent") if err != nil { @@ -41,7 +37,6 @@ func TestServiceToken_SecretsGetWithoutImportsAndWithoutRecursiveCmd(t *testing. } func TestUniversalAuth_SecretsGetWithImportsAndRecursiveCmd(t *testing.T) { - SetupCli(t) MachineIdentityLoginCmd(t) output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--recursive", "--silent") @@ -58,7 +53,6 @@ func TestUniversalAuth_SecretsGetWithImportsAndRecursiveCmd(t *testing.T) { } func TestUniversalAuth_SecretsGetWithoutImportsAndWithoutRecursiveCmd(t *testing.T) { - SetupCli(t) MachineIdentityLoginCmd(t) output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--include-imports=false", "--silent") @@ -75,7 +69,6 @@ func TestUniversalAuth_SecretsGetWithoutImportsAndWithoutRecursiveCmd(t *testing } func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) { - SetupCli(t) MachineIdentityLoginCmd(t) output, _ := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--token", creds.UAAccessToken, "--projectId", creds.ProjectID, "--env", "invalid-env", "--recursive", "--silent") @@ -89,9 +82,6 @@ func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) { } func TestUserAuth_SecretsGetAll(t *testing.T) { - SetupCli(t) - UserLoginCmd(t); - output, err := ExecuteCliCommand(FORMATTED_CLI_NAME, "secrets", "--projectId", creds.ProjectID, "--env", creds.EnvSlug, "--include-imports=false", "--silent") if err != nil { t.Fatalf("error running CLI command: %v", err) From 24f7ecc548e5d8336324acf296f3653c99532d59 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 1 May 2024 21:41:07 +0800 Subject: [PATCH 11/23] misc: removed infisical init logs --- cli/test/login_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli/test/login_test.go b/cli/test/login_test.go index 2bc356855..1ee9d50a4 100644 --- a/cli/test/login_test.go +++ b/cli/test/login_test.go @@ -1,7 +1,6 @@ package tests import ( - "fmt" "log" "os/exec" "strings" @@ -28,7 +27,6 @@ func UserInitCmd() { n, err := ptmx.Read(buf) if n > 0 { terminalOut := string(buf) - fmt.Println("Terminal out is", terminalOut) if strings.Contains(terminalOut, "Which Infisical organization would you like to select a project from?") && step < 0 { step += 1 stepChan <- step From 8fc4fd64f84d4ff780f0bde1a755313d356e795a Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 2 May 2024 00:49:29 +0800 Subject: [PATCH 12/23] adjustment: moved backup logic to cmd layer --- cli/packages/cmd/run.go | 91 +++++++++++++++++++++++++++--------- cli/packages/util/secrets.go | 25 +--------- 2 files changed, 71 insertions(+), 45 deletions(-) diff --git a/cli/packages/cmd/run.go b/cli/packages/cmd/run.go index 04fe2588b..58088f5d3 100644 --- a/cli/packages/cmd/run.go +++ b/cli/packages/cmd/run.go @@ -116,35 +116,82 @@ var runCmd = &cobra.Command{ Recursive: recursive, } + var secrets []models.SingleEnvironmentVariable + var isUserSession bool + var infisicalDotJson models.WorkspaceConfigFile + var userBackupSecretsEncryptionKey []byte + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { request.UniversalAuthAccessToken = token.Token - } - - secrets, err := util.GetAllEnvironmentVariables(request, projectConfigDir) - - if err != nil { - util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid") - } - - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } - - if shouldExpandSecrets { - - authParams := models.ExpandSecretsAuthentication{} - - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - authParams.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - authParams.UniversalAuthAccessToken = token.Token + // user session + isUserSession = true + loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() + if err != nil { + util.HandleError(err) } - secrets = util.ExpandSecrets(secrets, authParams, projectConfigDir) + isConnected := util.CheckIsConnectedToInfisicalAPI() + + if projectConfigDir == "" { + projectConfig, err := util.GetWorkSpaceFromFile() + if err != nil { + util.HandleError(err) + } + + infisicalDotJson = projectConfig + } else { + projectConfig, err := util.GetWorkSpaceFromFilePath(projectConfigDir) + if err != nil { + util.HandleError(err) + } + + infisicalDotJson = projectConfig + } + + userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] + + if !isConnected { + secrets, err = util.ReadBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) + if err != nil { + util.HandleError(err) + } + if len(secrets) > 0 { + util.PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") + } + } + } + + if len(secrets) == 0 { + secrets, err = util.GetAllEnvironmentVariables(request, projectConfigDir) + if err != nil { + util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid") + } + + if secretOverriding { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) + } else { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) + } + + if shouldExpandSecrets { + + authParams := models.ExpandSecretsAuthentication{} + + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { + authParams.InfisicalToken = token.Token + } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { + authParams.UniversalAuthAccessToken = token.Token + } + + secrets = util.ExpandSecrets(secrets, authParams, projectConfigDir) + } + + if isUserSession { + util.WriteBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey, secrets) + } } secretsByKey := getSecretsByKeys(secrets) diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 0ca66cc4f..2e9b0ffd2 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -319,21 +319,16 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo } RequireLogin() - log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") loggedInUserDetails, err := GetCurrentLoggedInUserDetails() - isConnected := CheckIsConnectedToInfisicalAPI() - - if isConnected { - log.Debug().Msg("GetAllEnvironmentVariables: Connected to Infisical instance, checking logged in creds") - } + log.Debug().Msg("GetAllEnvironmentVariables: Connected to Infisical instance, checking logged in creds") if err != nil { return nil, err } - if isConnected && loggedInUserDetails.LoginExpired { + if loggedInUserDetails.LoginExpired { PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again") } @@ -362,22 +357,6 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo secretsToReturn, errorToReturn = GetPlainTextSecretsViaJTW(loggedInUserDetails.UserCredentials.JTWToken, loggedInUserDetails.UserCredentials.PrivateKey, infisicalDotJson.WorkspaceId, params.Environment, params.TagSlugs, params.SecretsPath, params.IncludeImport, params.Recursive) log.Debug().Msgf("GetAllEnvironmentVariables: Trying to fetch secrets JTW token [err=%s]", errorToReturn) - - backupSecretsEncryptionKey := []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - if errorToReturn == nil { - WriteBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey, secretsToReturn) - } - - // only attempt to serve cached secrets if no internet connection and if at least one secret cached - if !isConnected { - backedSecrets, err := ReadBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey) - if len(backedSecrets) > 0 { - PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") - secretsToReturn = backedSecrets - errorToReturn = err - } - } - } else { if params.InfisicalToken != "" { log.Debug().Msg("Trying to fetch secrets using service token") From 920b9a7dfae115431ed8dc5a5f00f320a8d28585 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 2 May 2024 00:59:17 +0800 Subject: [PATCH 13/23] adjustment: moved secret backup logic to cmd layer --- cli/packages/cmd/secrets.go | 79 +++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/cli/packages/cmd/secrets.go b/cli/packages/cmd/secrets.go index 305a1f0fd..0a800580f 100644 --- a/cli/packages/cmd/secrets.go +++ b/cli/packages/cmd/secrets.go @@ -88,37 +88,74 @@ var secretsCmd = &cobra.Command{ Recursive: recursive, } + var secrets []models.SingleEnvironmentVariable + var isUserSession bool + var infisicalDotJson models.WorkspaceConfigFile + var userBackupSecretsEncryptionKey []byte + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { request.UniversalAuthAccessToken = token.Token - } - - secrets, err := util.GetAllEnvironmentVariables(request, "") - if err != nil { - util.HandleError(err) - } - - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } + // user session + isUserSession = true + loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() + if err != nil { + util.HandleError(err) + } + + isConnected := util.CheckIsConnectedToInfisicalAPI() - if shouldExpandSecrets { - - authParams := models.ExpandSecretsAuthentication{} - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - authParams.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - authParams.UniversalAuthAccessToken = token.Token + projectConfig, err := util.GetWorkSpaceFromFile() + if err != nil { + util.HandleError(err) } - secrets = util.ExpandSecrets(secrets, authParams, "") + infisicalDotJson = projectConfig + userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] + + if !isConnected { + secrets, err = util.ReadBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) + if err != nil { + util.HandleError(err) + } + if len(secrets) > 0 { + util.PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") + } + } } - // Sort the secrets by key so we can create a consistent output - secrets = util.SortSecretsByKeys(secrets) + if len(secrets) == 0 { + secrets, err = util.GetAllEnvironmentVariables(request, "") + if err != nil { + util.HandleError(err) + } + + if secretOverriding { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) + } else { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) + } + + if shouldExpandSecrets { + + authParams := models.ExpandSecretsAuthentication{} + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { + authParams.InfisicalToken = token.Token + } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { + authParams.UniversalAuthAccessToken = token.Token + } + + secrets = util.ExpandSecrets(secrets, authParams, "") + } + + // Sort the secrets by key so we can create a consistent output + secrets = util.SortSecretsByKeys(secrets) + if isUserSession { + util.WriteBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey, secrets) + } + } visualize.PrintAllSecretDetails(secrets) Telemetry.CaptureEvent("cli-command:secrets", posthog.NewProperties().Set("secretCount", len(secrets)).Set("version", util.CLI_VERSION)) From 04dca9432ddaabc8f3d2d762fd765d6a39c55e30 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 2 May 2024 01:09:12 +0800 Subject: [PATCH 14/23] misc: updated test comment --- cli/test/secrets_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/test/secrets_test.go b/cli/test/secrets_test.go index 7af64eab8..f5d5a7b1f 100644 --- a/cli/test/secrets_test.go +++ b/cli/test/secrets_test.go @@ -93,7 +93,7 @@ func TestUserAuth_SecretsGetAll(t *testing.T) { t.Fatalf("snapshot failed: %v", err) } - // intentionally invoked this here because it should directly follow secretsGetAll + // explicitly called here because it should happen directly after successful secretsGetAll testUserAuth_SecretsGetAllWithoutConnection(t) } From a1e8f45a8692587a0a80571af883690a60f628b0 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 2 May 2024 01:35:19 +0800 Subject: [PATCH 15/23] misc: added new cli secrets to release build gh action --- .github/workflows/release_build_infisical_cli.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release_build_infisical_cli.yml b/.github/workflows/release_build_infisical_cli.yml index e4a5945e0..af8e28f4d 100644 --- a/.github/workflows/release_build_infisical_cli.yml +++ b/.github/workflows/release_build_infisical_cli.yml @@ -22,6 +22,9 @@ jobs: CLI_TESTS_SERVICE_TOKEN: ${{ secrets.CLI_TESTS_SERVICE_TOKEN }} CLI_TESTS_PROJECT_ID: ${{ secrets.CLI_TESTS_PROJECT_ID }} CLI_TESTS_ENV_SLUG: ${{ secrets.CLI_TESTS_ENV_SLUG }} + CLI_TESTS_USER_EMAIL: ${{ secrets.CLI_TESTS_USER_EMAIL }} + CLI_TESTS_USER_PASSWORD: ${{ secrets.CLI_TESTS_USER_PASSWORD }} + INFISICAL_VAULT_FILE_PASSPHRASE: ${{ secrets.CLI_TESTS_INFISICAL_VAULT_FILE_PASSPHRASE }} goreleaser: runs-on: ubuntu-20.04 From 88a4fb84e66c5a68d7e6c9819f59c48713a060a5 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 2 May 2024 03:21:20 +0800 Subject: [PATCH 16/23] feature: added offline support for infisical export --- cli/packages/cmd/export.go | 83 +++++++++++++++++++++++------------- cli/packages/cmd/run.go | 13 +----- cli/packages/cmd/secrets.go | 13 +----- cli/packages/util/secrets.go | 18 ++++++++ 4 files changed, 73 insertions(+), 54 deletions(-) diff --git a/cli/packages/cmd/export.go b/cli/packages/cmd/export.go index 983c19255..271509b0c 100644 --- a/cli/packages/cmd/export.go +++ b/cli/packages/cmd/export.go @@ -93,10 +93,33 @@ var exportCmd = &cobra.Command{ IncludeImport: includeImports, } + + var secrets []models.SingleEnvironmentVariable + var isUserSession bool + var infisicalDotJson models.WorkspaceConfigFile + var userBackupSecretsEncryptionKey []byte + var loggedInUserDetails util.LoggedInUserDetails + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { request.UniversalAuthAccessToken = token.Token + } else { + isUserSession = true + loggedInUserDetails, err = util.GetCurrentLoggedInUserDetails() + if err != nil { + util.HandleError(err) + } + + projectConfig, err := util.GetWorkSpaceFromFile() + if err != nil { + util.HandleError(err) + } + + infisicalDotJson = projectConfig + + userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] + secrets = util.GetBackupSecretsIfDisconnected(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) } if templatePath != "" { @@ -109,10 +132,6 @@ var exportCmd = &cobra.Command{ accessToken = token.Token } else { log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") - loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() - if err != nil { - util.HandleError(err) - } accessToken = loggedInUserDetails.UserCredentials.JTWToken } @@ -124,40 +143,44 @@ var exportCmd = &cobra.Command{ return } - secrets, err := util.GetAllEnvironmentVariables(request, "") - if err != nil { - util.HandleError(err, "Unable to fetch secrets") - } - - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) - } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } - - var output string - if shouldExpandSecrets { - - authParams := models.ExpandSecretsAuthentication{} - - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - authParams.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - authParams.UniversalAuthAccessToken = token.Token + if len(secrets) == 0 { + secrets, err = util.GetAllEnvironmentVariables(request, "") + if err != nil { + util.HandleError(err, "Unable to fetch secrets") } - secrets = util.ExpandSecrets(secrets, authParams, "") - } - secrets = util.FilterSecretsByTag(secrets, tagSlugs) - secrets = util.SortSecretsByKeys(secrets) + if secretOverriding { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) + } else { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) + } - output, err = formatEnvs(secrets, format) + if shouldExpandSecrets { + + authParams := models.ExpandSecretsAuthentication{} + + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { + authParams.InfisicalToken = token.Token + } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { + authParams.UniversalAuthAccessToken = token.Token + } + + secrets = util.ExpandSecrets(secrets, authParams, "") + } + secrets = util.FilterSecretsByTag(secrets, tagSlugs) + secrets = util.SortSecretsByKeys(secrets) + + if isUserSession { + util.WriteBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey, secrets) + } + } + + output, err := formatEnvs(secrets, format) if err != nil { util.HandleError(err) } fmt.Print(output) - // Telemetry.CaptureEvent("cli-command:export", posthog.NewProperties().Set("secretsCount", len(secrets)).Set("version", util.CLI_VERSION)) }, } diff --git a/cli/packages/cmd/run.go b/cli/packages/cmd/run.go index 58088f5d3..0770a8556 100644 --- a/cli/packages/cmd/run.go +++ b/cli/packages/cmd/run.go @@ -133,8 +133,6 @@ var runCmd = &cobra.Command{ util.HandleError(err) } - isConnected := util.CheckIsConnectedToInfisicalAPI() - if projectConfigDir == "" { projectConfig, err := util.GetWorkSpaceFromFile() if err != nil { @@ -152,16 +150,7 @@ var runCmd = &cobra.Command{ } userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - - if !isConnected { - secrets, err = util.ReadBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) - if err != nil { - util.HandleError(err) - } - if len(secrets) > 0 { - util.PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") - } - } + secrets = util.GetBackupSecretsIfDisconnected(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) } if len(secrets) == 0 { diff --git a/cli/packages/cmd/secrets.go b/cli/packages/cmd/secrets.go index 0a800580f..cd31d05e9 100644 --- a/cli/packages/cmd/secrets.go +++ b/cli/packages/cmd/secrets.go @@ -105,8 +105,6 @@ var secretsCmd = &cobra.Command{ util.HandleError(err) } - isConnected := util.CheckIsConnectedToInfisicalAPI() - projectConfig, err := util.GetWorkSpaceFromFile() if err != nil { util.HandleError(err) @@ -114,16 +112,7 @@ var secretsCmd = &cobra.Command{ infisicalDotJson = projectConfig userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - - if !isConnected { - secrets, err = util.ReadBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) - if err != nil { - util.HandleError(err) - } - if len(secrets) > 0 { - util.PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") - } - } + secrets = util.GetBackupSecretsIfDisconnected(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) } if len(secrets) == 0 { diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 2e9b0ffd2..e97dda9b0 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -426,6 +426,24 @@ func getSecretsByKeys(secrets []models.SingleEnvironmentVariable) map[string]mod return secretMapByName } +func GetBackupSecretsIfDisconnected(workspaceId string, environment string, encryptionKey []byte) ([]models.SingleEnvironmentVariable) { + isConnected := CheckIsConnectedToInfisicalAPI() + + if !isConnected { + secrets, err := ReadBackupSecrets(workspaceId, environment, encryptionKey) + if err != nil { + HandleError(err) + } + if len(secrets) > 0 { + PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") + } + + return secrets + } + + return nil +} + func ExpandSecrets(secrets []models.SingleEnvironmentVariable, auth models.ExpandSecretsAuthentication, projectConfigPathDir string) []models.SingleEnvironmentVariable { expandedSecs := make(map[string]string) interpolatedSecs := make(map[string]string) From 6c252b4bfb8490034b785e1d7bd65146b3ae1d67 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 00:49:57 +0800 Subject: [PATCH 17/23] misc: revert backup flow modification for run.go --- cli/packages/cmd/run.go | 78 +++++++++++------------------------------ 1 file changed, 21 insertions(+), 57 deletions(-) diff --git a/cli/packages/cmd/run.go b/cli/packages/cmd/run.go index 0770a8556..04fe2588b 100644 --- a/cli/packages/cmd/run.go +++ b/cli/packages/cmd/run.go @@ -116,71 +116,35 @@ var runCmd = &cobra.Command{ Recursive: recursive, } - var secrets []models.SingleEnvironmentVariable - var isUserSession bool - var infisicalDotJson models.WorkspaceConfigFile - var userBackupSecretsEncryptionKey []byte - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { request.UniversalAuthAccessToken = token.Token - } else { - // user session - isUserSession = true - loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() - if err != nil { - util.HandleError(err) - } - - if projectConfigDir == "" { - projectConfig, err := util.GetWorkSpaceFromFile() - if err != nil { - util.HandleError(err) - } - - infisicalDotJson = projectConfig - } else { - projectConfig, err := util.GetWorkSpaceFromFilePath(projectConfigDir) - if err != nil { - util.HandleError(err) - } - - infisicalDotJson = projectConfig - } - - userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - secrets = util.GetBackupSecretsIfDisconnected(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) } - if len(secrets) == 0 { - secrets, err = util.GetAllEnvironmentVariables(request, projectConfigDir) - if err != nil { - util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid") + secrets, err := util.GetAllEnvironmentVariables(request, projectConfigDir) + + if err != nil { + util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid") + } + + if secretOverriding { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) + } else { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) + } + + if shouldExpandSecrets { + + authParams := models.ExpandSecretsAuthentication{} + + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { + authParams.InfisicalToken = token.Token + } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { + authParams.UniversalAuthAccessToken = token.Token } - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) - } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } - - if shouldExpandSecrets { - - authParams := models.ExpandSecretsAuthentication{} - - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - authParams.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - authParams.UniversalAuthAccessToken = token.Token - } - - secrets = util.ExpandSecrets(secrets, authParams, projectConfigDir) - } - - if isUserSession { - util.WriteBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey, secrets) - } + secrets = util.ExpandSecrets(secrets, authParams, projectConfigDir) } secretsByKey := getSecretsByKeys(secrets) From a1b41ca4541a3d220b1376dc9dcd41961733393e Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 00:52:59 +0800 Subject: [PATCH 18/23] Revert "feature: added offline support for infisical export" This reverts commit 88a4fb84e66c5a68d7e6c9819f59c48713a060a5. --- cli/packages/cmd/export.go | 85 +++++++++++++----------------------- cli/packages/cmd/secrets.go | 13 +++++- cli/packages/util/secrets.go | 18 -------- 3 files changed, 43 insertions(+), 73 deletions(-) diff --git a/cli/packages/cmd/export.go b/cli/packages/cmd/export.go index 271509b0c..983c19255 100644 --- a/cli/packages/cmd/export.go +++ b/cli/packages/cmd/export.go @@ -93,33 +93,10 @@ var exportCmd = &cobra.Command{ IncludeImport: includeImports, } - - var secrets []models.SingleEnvironmentVariable - var isUserSession bool - var infisicalDotJson models.WorkspaceConfigFile - var userBackupSecretsEncryptionKey []byte - var loggedInUserDetails util.LoggedInUserDetails - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { request.UniversalAuthAccessToken = token.Token - } else { - isUserSession = true - loggedInUserDetails, err = util.GetCurrentLoggedInUserDetails() - if err != nil { - util.HandleError(err) - } - - projectConfig, err := util.GetWorkSpaceFromFile() - if err != nil { - util.HandleError(err) - } - - infisicalDotJson = projectConfig - - userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - secrets = util.GetBackupSecretsIfDisconnected(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) } if templatePath != "" { @@ -132,6 +109,10 @@ var exportCmd = &cobra.Command{ accessToken = token.Token } else { log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") + loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() + if err != nil { + util.HandleError(err) + } accessToken = loggedInUserDetails.UserCredentials.JTWToken } @@ -143,44 +124,40 @@ var exportCmd = &cobra.Command{ return } - if len(secrets) == 0 { - secrets, err = util.GetAllEnvironmentVariables(request, "") - if err != nil { - util.HandleError(err, "Unable to fetch secrets") - } - - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) - } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } - - if shouldExpandSecrets { - - authParams := models.ExpandSecretsAuthentication{} - - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - authParams.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - authParams.UniversalAuthAccessToken = token.Token - } - - secrets = util.ExpandSecrets(secrets, authParams, "") - } - secrets = util.FilterSecretsByTag(secrets, tagSlugs) - secrets = util.SortSecretsByKeys(secrets) - - if isUserSession { - util.WriteBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey, secrets) - } + secrets, err := util.GetAllEnvironmentVariables(request, "") + if err != nil { + util.HandleError(err, "Unable to fetch secrets") } - output, err := formatEnvs(secrets, format) + if secretOverriding { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) + } else { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) + } + + var output string + if shouldExpandSecrets { + + authParams := models.ExpandSecretsAuthentication{} + + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { + authParams.InfisicalToken = token.Token + } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { + authParams.UniversalAuthAccessToken = token.Token + } + + secrets = util.ExpandSecrets(secrets, authParams, "") + } + secrets = util.FilterSecretsByTag(secrets, tagSlugs) + secrets = util.SortSecretsByKeys(secrets) + + output, err = formatEnvs(secrets, format) if err != nil { util.HandleError(err) } fmt.Print(output) + // Telemetry.CaptureEvent("cli-command:export", posthog.NewProperties().Set("secretsCount", len(secrets)).Set("version", util.CLI_VERSION)) }, } diff --git a/cli/packages/cmd/secrets.go b/cli/packages/cmd/secrets.go index d5ad8b403..4b65a11db 100644 --- a/cli/packages/cmd/secrets.go +++ b/cli/packages/cmd/secrets.go @@ -105,6 +105,8 @@ var secretsCmd = &cobra.Command{ util.HandleError(err) } + isConnected := util.CheckIsConnectedToInfisicalAPI() + projectConfig, err := util.GetWorkSpaceFromFile() if err != nil { util.HandleError(err) @@ -112,7 +114,16 @@ var secretsCmd = &cobra.Command{ infisicalDotJson = projectConfig userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - secrets = util.GetBackupSecretsIfDisconnected(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) + + if !isConnected { + secrets, err = util.ReadBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) + if err != nil { + util.HandleError(err) + } + if len(secrets) > 0 { + util.PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") + } + } } if len(secrets) == 0 { diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index e97dda9b0..2e9b0ffd2 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -426,24 +426,6 @@ func getSecretsByKeys(secrets []models.SingleEnvironmentVariable) map[string]mod return secretMapByName } -func GetBackupSecretsIfDisconnected(workspaceId string, environment string, encryptionKey []byte) ([]models.SingleEnvironmentVariable) { - isConnected := CheckIsConnectedToInfisicalAPI() - - if !isConnected { - secrets, err := ReadBackupSecrets(workspaceId, environment, encryptionKey) - if err != nil { - HandleError(err) - } - if len(secrets) > 0 { - PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") - } - - return secrets - } - - return nil -} - func ExpandSecrets(secrets []models.SingleEnvironmentVariable, auth models.ExpandSecretsAuthentication, projectConfigPathDir string) []models.SingleEnvironmentVariable { expandedSecs := make(map[string]string) interpolatedSecs := make(map[string]string) From 9db5be1c91e34aa6a01b034c2517a7d6cfb60d18 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 00:58:36 +0800 Subject: [PATCH 19/23] Revert "adjustment: moved secret backup logic to cmd layer" This reverts commit 920b9a7dfae115431ed8dc5a5f00f320a8d28585. --- cli/packages/cmd/secrets.go | 79 ++++++++++--------------------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/cli/packages/cmd/secrets.go b/cli/packages/cmd/secrets.go index 4b65a11db..423fe1657 100644 --- a/cli/packages/cmd/secrets.go +++ b/cli/packages/cmd/secrets.go @@ -88,75 +88,38 @@ var secretsCmd = &cobra.Command{ Recursive: recursive, } - var secrets []models.SingleEnvironmentVariable - var isUserSession bool - var infisicalDotJson models.WorkspaceConfigFile - var userBackupSecretsEncryptionKey []byte - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { request.UniversalAuthAccessToken = token.Token + } + + secrets, err := util.GetAllEnvironmentVariables(request, "") + if err != nil { + util.HandleError(err) + } + + if secretOverriding { + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) } else { - // user session - isUserSession = true - loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() - if err != nil { - util.HandleError(err) - } - - isConnected := util.CheckIsConnectedToInfisicalAPI() - - projectConfig, err := util.GetWorkSpaceFromFile() - if err != nil { - util.HandleError(err) - } - - infisicalDotJson = projectConfig - userBackupSecretsEncryptionKey = []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] - - if !isConnected { - secrets, err = util.ReadBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey) - if err != nil { - util.HandleError(err) - } - if len(secrets) > 0 { - util.PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") - } - } + secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) } - if len(secrets) == 0 { - secrets, err = util.GetAllEnvironmentVariables(request, "") - if err != nil { - util.HandleError(err) + if shouldExpandSecrets { + + authParams := models.ExpandSecretsAuthentication{} + if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { + authParams.InfisicalToken = token.Token + } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { + authParams.UniversalAuthAccessToken = token.Token } - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) - } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } - - if shouldExpandSecrets { - - authParams := models.ExpandSecretsAuthentication{} - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - authParams.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - authParams.UniversalAuthAccessToken = token.Token - } - - secrets = util.ExpandSecrets(secrets, authParams, "") - } - - // Sort the secrets by key so we can create a consistent output - secrets = util.SortSecretsByKeys(secrets) - if isUserSession { - util.WriteBackupSecrets(infisicalDotJson.WorkspaceId, environmentName, userBackupSecretsEncryptionKey, secrets) - } + secrets = util.ExpandSecrets(secrets, authParams, "") } + // Sort the secrets by key so we can create a consistent output + secrets = util.SortSecretsByKeys(secrets) + visualize.PrintAllSecretDetails(secrets) Telemetry.CaptureEvent("cli-command:secrets", posthog.NewProperties().Set("secretCount", len(secrets)).Set("version", util.CLI_VERSION)) }, From c9a95023be3bccc151253607055a267eced75953 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 01:03:26 +0800 Subject: [PATCH 20/23] Revert "adjustment: moved backup logic to cmd layer" This reverts commit 8fc4fd64f84d4ff780f0bde1a755313d356e795a. --- cli/packages/util/secrets.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 2e9b0ffd2..0ca66cc4f 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -319,16 +319,21 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo } RequireLogin() + log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") loggedInUserDetails, err := GetCurrentLoggedInUserDetails() - log.Debug().Msg("GetAllEnvironmentVariables: Connected to Infisical instance, checking logged in creds") + isConnected := CheckIsConnectedToInfisicalAPI() + + if isConnected { + log.Debug().Msg("GetAllEnvironmentVariables: Connected to Infisical instance, checking logged in creds") + } if err != nil { return nil, err } - if loggedInUserDetails.LoginExpired { + if isConnected && loggedInUserDetails.LoginExpired { PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again") } @@ -357,6 +362,22 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo secretsToReturn, errorToReturn = GetPlainTextSecretsViaJTW(loggedInUserDetails.UserCredentials.JTWToken, loggedInUserDetails.UserCredentials.PrivateKey, infisicalDotJson.WorkspaceId, params.Environment, params.TagSlugs, params.SecretsPath, params.IncludeImport, params.Recursive) log.Debug().Msgf("GetAllEnvironmentVariables: Trying to fetch secrets JTW token [err=%s]", errorToReturn) + + backupSecretsEncryptionKey := []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] + if errorToReturn == nil { + WriteBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey, secretsToReturn) + } + + // only attempt to serve cached secrets if no internet connection and if at least one secret cached + if !isConnected { + backedSecrets, err := ReadBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey) + if len(backedSecrets) > 0 { + PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") + secretsToReturn = backedSecrets + errorToReturn = err + } + } + } else { if params.InfisicalToken != "" { log.Debug().Msg("Trying to fetch secrets using service token") From 69b76aea640074533eccbe4c1a3022b6e2a82960 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 01:45:34 +0800 Subject: [PATCH 21/23] misc: added secrets folder path to backup scoping --- cli/packages/util/secrets.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 0ca66cc4f..74b052629 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -365,12 +365,12 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo backupSecretsEncryptionKey := []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32] if errorToReturn == nil { - WriteBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey, secretsToReturn) + WriteBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, params.SecretsPath, backupSecretsEncryptionKey, secretsToReturn) } // only attempt to serve cached secrets if no internet connection and if at least one secret cached if !isConnected { - backedSecrets, err := ReadBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey) + backedSecrets, err := ReadBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, params.SecretsPath, backupSecretsEncryptionKey) if len(backedSecrets) > 0 { PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug") secretsToReturn = backedSecrets @@ -635,8 +635,9 @@ func GetPlainTextSecrets(key []byte, encryptedSecrets []api.EncryptedSecretV3) ( return plainTextSecrets, nil } -func WriteBackupSecrets(workspace string, environment string, encryptionKey []byte, secrets []models.SingleEnvironmentVariable) error { - fileName := fmt.Sprintf("secrets_%s_%s", workspace, environment) +func WriteBackupSecrets(workspace string, environment string, secretsPath string, encryptionKey []byte, secrets []models.SingleEnvironmentVariable) error { + formattedPath := strings.ReplaceAll(secretsPath, "/", "-") + fileName := fmt.Sprintf("secrets_%s_%s_%s", workspace, environment, formattedPath) secrets_backup_folder_name := "secrets-backup" _, fullConfigFileDirPath, err := GetFullConfigFilePath() @@ -673,8 +674,9 @@ func WriteBackupSecrets(workspace string, environment string, encryptionKey []by return nil } -func ReadBackupSecrets(workspace string, environment string, encryptionKey []byte) ([]models.SingleEnvironmentVariable, error) { - fileName := fmt.Sprintf("secrets_%s_%s", workspace, environment) +func ReadBackupSecrets(workspace string, environment string, secretsPath string, encryptionKey []byte) ([]models.SingleEnvironmentVariable, error) { + formattedPath := strings.ReplaceAll(secretsPath, "/", "-") + fileName := fmt.Sprintf("secrets_%s_%s_%s", workspace, environment, formattedPath) secrets_backup_folder_name := "secrets-backup" _, fullConfigFileDirPath, err := GetFullConfigFilePath() From cf9169ad6feace705296f6f635209d25cde00b61 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 03:37:51 +0800 Subject: [PATCH 22/23] test: resolved test issues --- cli/scripts/export_test_env.sh | 9 +++++---- cli/test/login_test.go | 21 ++++++++------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/cli/scripts/export_test_env.sh b/cli/scripts/export_test_env.sh index 08b5ad41b..0b242281d 100644 --- a/cli/scripts/export_test_env.sh +++ b/cli/scripts/export_test_env.sh @@ -9,14 +9,15 @@ if [ ! -f "$TEST_ENV_FILE" ]; then fi # Export the variables -while IFS='=' read -r key value +while IFS= read -r line do # Skip empty lines and lines starting with # - if [[ -z "$key" || "$key" =~ ^\# ]]; then + if [[ -z "$line" || "$line" =~ ^\# ]]; then continue fi - # Use eval to correctly handle values with spaces - eval export $key='$value' + # Read the key-value pair + IFS='=' read -r key value <<< "$line" + eval export $key=\$value done < "$TEST_ENV_FILE" echo "Test environment variables set." diff --git a/cli/test/login_test.go b/cli/test/login_test.go index 1ee9d50a4..71273a3ec 100644 --- a/cli/test/login_test.go +++ b/cli/test/login_test.go @@ -77,22 +77,19 @@ func UserLoginCmd() { n, err := ptmx.Read(buf) if n > 0 { terminalOut := string(buf) - if strings.Contains(terminalOut, "Add a new account") && step < 0 { - step += 1 - stepChan <- step - } else if strings.Contains(terminalOut, "Infisical Cloud") && step < 1 { + if strings.Contains(terminalOut, "Infisical Cloud") && step < 0 { step += 1; stepChan <- step - } else if strings.Contains(terminalOut, "Email") && step < 2 { + } else if strings.Contains(terminalOut, "Email") && step < 1 { step += 1; stepChan <- step - } else if strings.Contains(terminalOut, "Password") && step < 3 { + } else if strings.Contains(terminalOut, "Password") && step < 2 { step += 1; stepChan <- step - } else if strings.Contains(terminalOut, "Infisical organization") && step < 4 { + } else if strings.Contains(terminalOut, "Infisical organization") && step < 3 { step += 1; stepChan <- step - } else if strings.Contains(terminalOut, "Enter passphrase") && step < 5 { + } else if strings.Contains(terminalOut, "Enter passphrase") && step < 4 { step += 1; stepChan <- step } @@ -106,17 +103,15 @@ func UserLoginCmd() { for i := range stepChan { switch i { - case 0: + case 0: ptmx.Write([]byte("\n")) case 1: - ptmx.Write([]byte("\n")) - case 2: ptmx.Write([]byte(creds.UserEmail)) ptmx.Write([]byte("\n")) - case 3: + case 2: ptmx.Write([]byte(creds.UserPassword)) ptmx.Write([]byte("\n")) - case 4: + case 3: ptmx.Write([]byte("\n")) } } From dfdd8e95f9c15c13076d30a03b7e9ec370c2ceed Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 11 Jun 2024 22:14:19 +0800 Subject: [PATCH 23/23] misc: renamed connection check method --- cli/packages/util/common.go | 2 +- cli/packages/util/secrets.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/packages/util/common.go b/cli/packages/util/common.go index 42ee74c77..55907da9d 100644 --- a/cli/packages/util/common.go +++ b/cli/packages/util/common.go @@ -23,7 +23,7 @@ func WriteToFile(fileName string, dataToWrite []byte, filePerm os.FileMode) erro return nil } -func CheckIsConnectedToInfisicalAPI() (ok bool) { +func ValidateInfisicalAPIConnection() (ok bool) { _, err := http.Get(fmt.Sprintf("%v/status", config.INFISICAL_URL)) return err == nil } diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 74b052629..02c2704bd 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -323,7 +323,7 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectCo log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details") loggedInUserDetails, err := GetCurrentLoggedInUserDetails() - isConnected := CheckIsConnectedToInfisicalAPI() + isConnected := ValidateInfisicalAPIConnection() if isConnected { log.Debug().Msg("GetAllEnvironmentVariables: Connected to Infisical instance, checking logged in creds")