diff --git a/config/config.go b/config/config.go index 1e39d6e..f29a746 100644 --- a/config/config.go +++ b/config/config.go @@ -379,11 +379,11 @@ func Get() *RuntimeConfig { return globalConfig } -func ConfigureSandbox(isInstallationCommand bool) { +func ConfigureSandbox(mayDownloadPackages bool) { if globalConfig.Config.Sandbox.Enabled { // Apply sandbox to all commands if EnforceAlways=true, otherwise only to - // installation commands else disable the sandbox - globalConfig.Config.Sandbox.Enabled = globalConfig.Config.Sandbox.EnforceAlways || isInstallationCommand + // commands that may download packages (install, update, etc.) + globalConfig.Config.Sandbox.Enabled = globalConfig.Config.Sandbox.EnforceAlways || mayDownloadPackages } } diff --git a/config/config_test.go b/config/config_test.go index 891a22f..28e0819 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -221,6 +221,64 @@ func TestConfigPrecedence(t *testing.T) { }) } +func TestConfigureSandbox(t *testing.T) { + tests := []struct { + name string + sandboxEnabled bool + enforceAlways bool + mayDownloadPackages bool + expectedSandboxState bool + }{ + { + name: "sandbox disabled stays disabled regardless of command", + sandboxEnabled: false, + mayDownloadPackages: true, + expectedSandboxState: false, + }, + { + name: "sandbox enabled with download command stays enabled", + sandboxEnabled: true, + mayDownloadPackages: true, + expectedSandboxState: true, + }, + { + name: "sandbox enabled with non-download command gets disabled", + sandboxEnabled: true, + mayDownloadPackages: false, + expectedSandboxState: false, + }, + { + name: "enforce_always keeps sandbox enabled for non-download command", + sandboxEnabled: true, + enforceAlways: true, + mayDownloadPackages: false, + expectedSandboxState: true, + }, + { + name: "enforce_always with download command stays enabled", + sandboxEnabled: true, + enforceAlways: true, + mayDownloadPackages: true, + expectedSandboxState: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + t.Setenv("PMG_CONFIG_DIR", "/tmp/pmg-test/random-does-not-exist") + initConfig() + + cfg := Get() + cfg.Config.Sandbox.Enabled = tc.sandboxEnabled + cfg.Config.Sandbox.EnforceAlways = tc.enforceAlways + + ConfigureSandbox(tc.mayDownloadPackages) + + assert.Equal(t, tc.expectedSandboxState, cfg.Config.Sandbox.Enabled) + }) + } +} + func TestWriteTemplateConfigMergesExistingConfig(t *testing.T) { tmpDir := t.TempDir() t.Setenv("PMG_CONFIG_DIR", tmpDir) diff --git a/internal/flows/common_flow.go b/internal/flows/common_flow.go index df2f702..9dc413d 100644 --- a/internal/flows/common_flow.go +++ b/internal/flows/common_flow.go @@ -34,7 +34,7 @@ func (f *commonFlow) Run(ctx context.Context, args []string, parsedCmd *packagem var analyzers []analyzer.PackageVersionAnalyzer // Configure sandbox based on command type and enforcement policy - config.ConfigureSandbox(parsedCmd.IsInstallationCommand()) + config.ConfigureSandbox(parsedCmd.IsInstallationCommand() || parsedCmd.MayDownloadPackages()) cfg := config.Get() diff --git a/internal/flows/proxy_flow.go b/internal/flows/proxy_flow.go index bca5f02..6f7b512 100644 --- a/internal/flows/proxy_flow.go +++ b/internal/flows/proxy_flow.go @@ -48,7 +48,7 @@ func (f *proxyFlow) Run(ctx context.Context, args []string, parsedCmd *packagema } // Configure sandbox based on command type and enforcement policy - config.ConfigureSandbox(parsedCmd.IsInstallationCommand()) + config.ConfigureSandbox(parsedCmd.IsInstallationCommand() || parsedCmd.MayDownloadPackages()) cfg := config.Get()