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",
|
OSExecShell: "/bin/bash",
|
||||||
Permissions: scriptmanager.Permissions{
|
Permissions: scriptmanager.Permissions{
|
||||||
AllowShellCommands: true,
|
AllowShellCommands: true,
|
||||||
|
AllowEnv: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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{}
|
||||||
|
|
Loading…
Reference in a new issue