diff --git a/.gitignore b/.gitignore index f2a23324b..f21c85c41 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.direnv/ + # backend node_modules .env @@ -26,8 +28,6 @@ node_modules /.pnp .pnp.js -.env - # testing coverage reports @@ -63,10 +63,12 @@ yarn-error.log* # Editor specific .vscode/* -.idea/* +**/.idea/* frontend-build +# cli +.go/ *.tgz cli/infisical-merge cli/test/infisical-merge diff --git a/cli/packages/api/model.go b/cli/packages/api/model.go index 72dbbc97b..1eb936f24 100644 --- a/cli/packages/api/model.go +++ b/cli/packages/api/model.go @@ -2,6 +2,12 @@ package api import "time" +type Environment struct { + Name string `json:"name"` + Slug string `json:"slug"` + ID string `json:"id"` +} + // Stores info for login one type LoginOneRequest struct { Email string `json:"email"` @@ -14,7 +20,6 @@ type LoginOneResponse struct { } // Stores info for login two - type LoginTwoRequest struct { Email string `json:"email"` ClientProof string `json:"clientProof"` @@ -168,9 +173,10 @@ type Secret struct { } type Project struct { - ID string `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Environments []Environment `json:"environments"` } type RawSecret struct { diff --git a/cli/packages/cmd/run.go b/cli/packages/cmd/run.go index 7f11a3f95..388a4861d 100644 --- a/cli/packages/cmd/run.go +++ b/cli/packages/cmd/run.go @@ -15,6 +15,9 @@ import ( "syscall" "time" + "github.com/Infisical/infisical-merge/packages/api" + "github.com/go-resty/resty/v2" + "github.com/Infisical/infisical-merge/packages/models" "github.com/Infisical/infisical-merge/packages/util" "github.com/fatih/color" @@ -59,11 +62,11 @@ var runCmd = &cobra.Command{ return nil }, Run: func(cmd *cobra.Command, args []string) { - environmentName, _ := cmd.Flags().GetString("env") + environmentSlug, _ := cmd.Flags().GetString("env") if !cmd.Flags().Changed("env") { environmentFromWorkspace := util.GetEnvFromWorkspaceFile() if environmentFromWorkspace != "" { - environmentName = environmentFromWorkspace + environmentSlug = environmentFromWorkspace } } @@ -136,8 +139,20 @@ var runCmd = &cobra.Command{ util.HandleError(err, "Unable to parse flag") } + log.Debug().Msgf("Confirming selected environment is valid: %s", environmentSlug) + + hasEnvironment, err := confirmProjectHasEnvironment(environmentSlug, projectId, token) + if err != nil { + util.HandleError(err, "Could not confirm project has environment") + } + if !hasEnvironment { + util.HandleError(fmt.Errorf("project does not have environment '%s'", environmentSlug)) + } + + log.Debug().Msgf("Project '%s' has environment '%s'", projectId, environmentSlug) + request := models.GetAllSecretsParameters{ - Environment: environmentName, + Environment: environmentSlug, WorkspaceId: projectId, TagSlugs: tagSlugs, SecretsPath: secretsPath, @@ -308,7 +323,6 @@ func waitForExitCommand(cmd *exec.Cmd) (int, error) { } func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInterval int, request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) { - var cmd *exec.Cmd var err error var lastSecretsFetch time.Time @@ -439,8 +453,53 @@ func executeCommandWithWatchMode(commandFlag string, args []string, watchModeInt } } -func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) { +func confirmProjectHasEnvironment(environmentSlug, projectId string, token *models.TokenDetails) (bool, error) { + var accessToken string + if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) { + accessToken = token.Token + } else { + util.RequireLogin() + util.RequireLocalWorkspaceFile() + + loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true) + if err != nil { + util.HandleError(err, "Unable to authenticate") + } + + if loggedInUserDetails.LoginExpired { + util.PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again") + } + accessToken = loggedInUserDetails.UserCredentials.JTWToken + } + + if projectId == "" { + workspaceFile, err := util.GetWorkSpaceFromFile() + if err != nil { + util.HandleError(err, "Unable to get local project details") + } + + projectId = workspaceFile.WorkspaceId + } + + httpClient := resty.New() + httpClient.SetAuthToken(accessToken). + SetHeader("Accept", "application/json") + + project, err := api.CallGetProjectById(httpClient, projectId) + if err != nil { + return false, err + } + + for _, env := range project.Environments { + if env.Slug == environmentSlug { + return true, nil + } + } + return false, nil +} + +func fetchAndFormatSecretsForShell(request models.GetAllSecretsParameters, projectConfigDir string, secretOverriding bool, token *models.TokenDetails) (models.InjectableEnvironmentResult, error) { if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { request.InfisicalToken = token.Token } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 5a2a0ec24..0e26e03b0 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -232,7 +232,6 @@ func FilterSecretsByTag(plainTextSecrets []models.SingleEnvironmentVariable, tag func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) { var secretsToReturn []models.SingleEnvironmentVariable - // var serviceTokenDetails api.GetServiceTokenDetailsResponse var errorToReturn error if params.InfisicalToken == "" && params.UniversalAuthAccessToken == "" { diff --git a/cli/test/secrets_test.go b/cli/test/secrets_test.go index f7f0f13ff..642d33277 100644 --- a/cli/test/secrets_test.go +++ b/cli/test/secrets_test.go @@ -76,7 +76,6 @@ func TestUniversalAuth_SecretsGetWrongEnvironment(t *testing.T) { if err != nil { t.Fatalf("snapshot failed: %v", err) } - } func TestUserAuth_SecretsGetAll(t *testing.T) { diff --git a/flake.nix b/flake.nix index 094cfedc6..cc4cf8d65 100644 --- a/flake.nix +++ b/flake.nix @@ -14,11 +14,21 @@ git lazygit + go python312Full nodejs_20 nodePackages.prettier infisical ]; + + env = { + GOROOT = "${pkgs.go}/share/go"; + }; + + shellHook = '' + export GOPATH="$(pwd)/.go" + mkdir -p "$GOPATH" + ''; }; }; }