scripting: allowed access to environment variables (#41)

This commit is contained in:
Leon Mika 2023-01-11 21:44:22 +11:00 committed by GitHub
parent c89b09447c
commit 9e658b8619
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 0 deletions

View file

@ -65,6 +65,7 @@ func (sc *ScriptController) Init() {
OSExecShell: "/bin/bash", OSExecShell: "/bin/bash",
Permissions: scriptmanager.Permissions{ Permissions: scriptmanager.Permissions{
AllowShellCommands: true, AllowShellCommands: true,
AllowEnv: true,
}, },
}) })
} }

View file

@ -5,6 +5,7 @@ import (
"github.com/cloudcmds/tamarin/arg" "github.com/cloudcmds/tamarin/arg"
"github.com/cloudcmds/tamarin/object" "github.com/cloudcmds/tamarin/object"
"github.com/cloudcmds/tamarin/scope" "github.com/cloudcmds/tamarin/scope"
"os"
"os/exec" "os/exec"
) )
@ -35,12 +36,35 @@ func (om *osModule) exec(ctx context.Context, args ...object.Object) object.Obje
return object.NewOkResult(object.NewString(string(out))) return object.NewOkResult(object.NewString(string(out)))
} }
func (om *osModule) env(ctx context.Context, args ...object.Object) object.Object {
if err := arg.Require("os.env", 1, args); err != nil {
return err
}
cmdEnvName, objErr := object.AsString(args[0])
if objErr != nil {
return objErr
}
opts := optionFromCtx(ctx)
if !opts.Permissions.AllowEnv {
return object.Nil
}
envVal, hasVal := os.LookupEnv(cmdEnvName)
if !hasVal {
return object.Nil
}
return object.NewString(envVal)
}
func (om *osModule) register(scp *scope.Scope) { func (om *osModule) register(scp *scope.Scope) {
modScope := scope.New(scope.Opts{}) modScope := scope.New(scope.Opts{})
mod := object.NewModule("os", modScope) mod := object.NewModule("os", modScope)
modScope.AddBuiltins([]*object.Builtin{ modScope.AddBuiltins([]*object.Builtin{
object.NewBuiltin("exec", om.exec, mod), object.NewBuiltin("exec", om.exec, mod),
object.NewBuiltin("env", om.env, mod),
}) })
scp.Declare("os", mod, true) scp.Declare("os", mod, true)

View file

@ -9,6 +9,62 @@ import (
"testing" "testing"
) )
func TestOSModule_Env(t *testing.T) {
t.Run("should return value of environment variables", func(t *testing.T) {
t.Setenv("FULL_VALUE", "this is a value")
t.Setenv("EMPTY_VALUE", "")
testFS := testScriptFile(t, "test.tm", `
assert(os.env("FULL_VALUE") == "this is a value")
assert(os.env("EMPTY_VALUE") == "")
assert(os.env("MISSING_VALUE") == nil)
assert(bool(os.env("FULL_VALUE")) == true)
assert(bool(os.env("EMPTY_VALUE")) == false)
assert(bool(os.env("MISSING_VALUE")) == false)
`)
srv := scriptmanager.New(scriptmanager.WithFS(testFS))
srv.SetDefaultOptions(scriptmanager.Options{
OSExecShell: "/bin/bash",
Permissions: scriptmanager.Permissions{
AllowEnv: true,
},
})
ctx := context.Background()
err := <-srv.RunAdHocScript(ctx, "test.tm")
assert.NoError(t, err)
})
t.Run("should return nil when no access to environment variables", func(t *testing.T) {
t.Setenv("FULL_VALUE", "this is a value")
t.Setenv("EMPTY_VALUE", "")
testFS := testScriptFile(t, "test.tm", `
assert(os.env("FULL_VALUE") == nil)
assert(os.env("EMPTY_VALUE") == nil)
assert(os.env("MISSING_VALUE") == nil)
assert(bool(os.env("FULL_VALUE")) == false)
assert(bool(os.env("EMPTY_VALUE")) == false)
assert(bool(os.env("MISSING_VALUE")) == false)
`)
srv := scriptmanager.New(scriptmanager.WithFS(testFS))
srv.SetDefaultOptions(scriptmanager.Options{
OSExecShell: "/bin/bash",
Permissions: scriptmanager.Permissions{
AllowEnv: false,
},
})
ctx := context.Background()
err := <-srv.RunAdHocScript(ctx, "test.tm")
assert.NoError(t, err)
})
}
func TestOSModule_Exec(t *testing.T) { func TestOSModule_Exec(t *testing.T) {
t.Run("should run command and return stdout", func(t *testing.T) { t.Run("should run command and return stdout", func(t *testing.T) {
mockedUIService := mocks.NewUIService(t) mockedUIService := mocks.NewUIService(t)

View file

@ -29,6 +29,9 @@ func (opts Options) configuredShell() string {
type Permissions struct { type Permissions struct {
// AllowShellCommands determines whether or not a script can execute shell commands. // AllowShellCommands determines whether or not a script can execute shell commands.
AllowShellCommands bool AllowShellCommands bool
// AllowEnv determines whether or not a script can access environment variables
AllowEnv bool
} }
type optionCtxKeyType struct{} type optionCtxKeyType struct{}