scripting: allowed access to environment variables (#41)
This commit is contained in:
parent
c89b09447c
commit
9e658b8619
|
@ -65,6 +65,7 @@ func (sc *ScriptController) Init() {
|
|||
OSExecShell: "/bin/bash",
|
||||
Permissions: scriptmanager.Permissions{
|
||||
AllowShellCommands: true,
|
||||
AllowEnv: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/cloudcmds/tamarin/arg"
|
||||
"github.com/cloudcmds/tamarin/object"
|
||||
"github.com/cloudcmds/tamarin/scope"
|
||||
"os"
|
||||
"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)))
|
||||
}
|
||||
|
||||
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) {
|
||||
modScope := scope.New(scope.Opts{})
|
||||
mod := object.NewModule("os", modScope)
|
||||
|
||||
modScope.AddBuiltins([]*object.Builtin{
|
||||
object.NewBuiltin("exec", om.exec, mod),
|
||||
object.NewBuiltin("env", om.env, mod),
|
||||
})
|
||||
|
||||
scp.Declare("os", mod, true)
|
||||
|
|
|
@ -9,6 +9,62 @@ import (
|
|||
"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) {
|
||||
t.Run("should run command and return stdout", func(t *testing.T) {
|
||||
mockedUIService := mocks.NewUIService(t)
|
||||
|
|
|
@ -29,6 +29,9 @@ func (opts Options) configuredShell() string {
|
|||
type Permissions struct {
|
||||
// AllowShellCommands determines whether or not a script can execute shell commands.
|
||||
AllowShellCommands bool
|
||||
|
||||
// AllowEnv determines whether or not a script can access environment variables
|
||||
AllowEnv bool
|
||||
}
|
||||
|
||||
type optionCtxKeyType struct{}
|
||||
|
|
Loading…
Reference in a new issue