From d9ef77c5f2934ec91817b53501397642d45aa639 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 10 Apr 2025 22:41:33 -0400 Subject: [PATCH] Warn when not in a trusted directory --- cmd/root.go | 20 +++++-- cmd/root_test.go | 140 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 6 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 7959b0733..964cd7ad4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -49,18 +49,26 @@ func preRunEInitializeCommonComponents(cmd *cobra.Command, args []string) error return fmt.Errorf("Error creating common components: %w", err) } + // Resolve the shell and config handler + shell := controller.ResolveShell() + if shell != nil { + shell.SetVerbosity(verbose) + } + + // Check if we're in a trusted directory, but only for needed commands + cmdName := cmd.Name() + if cmdName != "hook" && cmdName != "init" && (cmdName != "env" || !cmd.Flags().Changed("decrypt")) { + if err := shell.CheckTrustedDirectory(); err != nil { + fmt.Fprintf(os.Stderr, "\033[33mWarning: You are not in a trusted directory. If you are in a Windsor project, run 'windsor init' to approve.\033[0m\n") + } + } + // Resolve the config handler configHandler := controller.ResolveConfigHandler() if configHandler == nil { return fmt.Errorf("No config handler found") } - // Set the verbosity - shell := controller.ResolveShell() - if shell != nil { - shell.SetVerbosity(verbose) - } - // Determine the cliConfig path var cliConfigPath string if cliConfigPath = os.Getenv("WINDSORCONFIG"); cliConfigPath == "" { diff --git a/cmd/root_test.go b/cmd/root_test.go index 62468392e..115f4cee0 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -246,4 +246,144 @@ func TestRoot_preRunEInitializeCommonComponents(t *testing.T) { } }) + t.Run("WarningInUntrustedDirectory", func(t *testing.T) { + // Setup mocks + mocks := setupSafeRootMocks() + mocks.Controller.ResolveShellFunc = func() shell.Shell { + return mocks.Shell + } + mocks.Shell.CheckTrustedDirectoryFunc = func() error { + return fmt.Errorf("Current directory not in the trusted list") + } + + // Create a command and register the controller + cmd := &cobra.Command{} + cmd.SetContext(context.WithValue(context.Background(), controllerKey, mocks.Controller)) + + // Capture stderr + output := captureStderr(func() { + // Run preRunEInitializeCommonComponents + err := preRunEInitializeCommonComponents(cmd, []string{}) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + }) + + // Check for warning message + expectedWarning := "Warning: You are not in a trusted directory" + if !strings.Contains(output, expectedWarning) { + t.Errorf("Expected output to contain %q, got %q", expectedWarning, output) + } + }) + + t.Run("NoWarningForHookCommand", func(t *testing.T) { + // Setup mocks + mocks := setupSafeRootMocks() + mocks.Shell.CheckTrustedDirectoryFunc = func() error { + return fmt.Errorf("Current directory not in the trusted list") + } + + // Capture stderr + output := captureStderr(func() { + // Create a hook command + cmd := hookCmd + cmd.SetArgs([]string{"bash"}) + + // Run preRunEInitializeCommonComponents + err := preRunEInitializeCommonComponents(cmd, []string{}) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + }) + + // Check that no warning was printed + unexpectedWarning := "Warning: You are not in a trusted directory" + if strings.Contains(output, unexpectedWarning) { + t.Errorf("Expected output to not contain %q, got %q", unexpectedWarning, output) + } + }) + + t.Run("NoWarningForEnvCommand", func(t *testing.T) { + // Setup mocks + mocks := setupSafeRootMocks() + mocks.Shell.CheckTrustedDirectoryFunc = func() error { + return fmt.Errorf("Current directory not in the trusted list") + } + + // Capture stderr + output := captureStderr(func() { + // Create an env command + cmd := envCmd + cmd.SetArgs([]string{}) + + // Run preRunEInitializeCommonComponents + err := preRunEInitializeCommonComponents(cmd, []string{}) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + }) + + // Check that no warning was printed + unexpectedWarning := "Warning: You are not in a trusted directory" + if strings.Contains(output, unexpectedWarning) { + t.Errorf("Expected output to not contain %q, got %q", unexpectedWarning, output) + } + }) + + t.Run("NoWarningForEnvCommandWithDecrypt", func(t *testing.T) { + // Setup mocks + mocks := setupSafeRootMocks() + mocks.Shell.CheckTrustedDirectoryFunc = func() error { + return fmt.Errorf("Current directory not in the trusted list") + } + + // Capture stderr + output := captureStderr(func() { + // Create an env command with --decrypt flag + cmd := envCmd + cmd.SetArgs([]string{"--decrypt"}) + + // Run preRunEInitializeCommonComponents + err := preRunEInitializeCommonComponents(cmd, []string{}) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + }) + + // Check that no warning was printed + unexpectedWarning := "Warning: You are not in a trusted directory" + if strings.Contains(output, unexpectedWarning) { + t.Errorf("Expected output to not contain %q, got %q", unexpectedWarning, output) + } + }) + + t.Run("WarningForEnvCommandWithoutDecrypt", func(t *testing.T) { + // Setup mocks + mocks := setupSafeRootMocks() + mocks.Controller.ResolveShellFunc = func() shell.Shell { + return mocks.Shell + } + mocks.Shell.CheckTrustedDirectoryFunc = func() error { + return fmt.Errorf("Current directory not in the trusted list") + } + + // Create a command and register the controller + cmd := &cobra.Command{Use: "env"} + cmd.SetContext(context.WithValue(context.Background(), controllerKey, mocks.Controller)) + + // Capture stderr + output := captureStderr(func() { + // Run preRunEInitializeCommonComponents + err := preRunEInitializeCommonComponents(cmd, []string{}) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + }) + + // Check for warning message + expectedWarning := "Warning: You are not in a trusted directory" + if !strings.Contains(output, expectedWarning) { + t.Errorf("Expected output to contain %q, got %q", expectedWarning, output) + } + }) }