mirror of https://github.com/ory/hydra
134 lines
2.9 KiB
Go
134 lines
2.9 KiB
Go
package jsonnetsecure
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/google/go-jsonnet"
|
|
)
|
|
|
|
type (
|
|
VM interface {
|
|
EvaluateAnonymousSnippet(filename string, snippet string) (json string, formattedErr error)
|
|
ExtCode(key string, val string)
|
|
ExtVar(key string, val string)
|
|
TLACode(key string, val string)
|
|
TLAVar(key string, val string)
|
|
}
|
|
|
|
kv struct {
|
|
Key, Value string
|
|
}
|
|
processParameters struct {
|
|
Filename, Snippet string
|
|
TLACodes, TLAVars, ExtCodes, ExtVars []kv
|
|
}
|
|
|
|
vmOptions struct {
|
|
jsonnetBinaryPath string
|
|
args []string
|
|
ctx context.Context
|
|
pool *pool
|
|
}
|
|
|
|
Option func(o *vmOptions)
|
|
)
|
|
|
|
func (pp *processParameters) EncodeTo(w io.Writer) error {
|
|
return json.NewEncoder(w).Encode(pp)
|
|
}
|
|
|
|
func (pp *processParameters) Decode(d []byte) error {
|
|
return json.Unmarshal(d, pp)
|
|
}
|
|
|
|
func newVMOptions() *vmOptions {
|
|
jsonnetBinaryPath, _ := os.Executable()
|
|
return &vmOptions{
|
|
jsonnetBinaryPath: jsonnetBinaryPath,
|
|
ctx: context.Background(),
|
|
}
|
|
}
|
|
|
|
func WithContext(ctx context.Context) Option {
|
|
return func(o *vmOptions) {
|
|
o.ctx = ctx
|
|
}
|
|
}
|
|
|
|
func WithProcessPool(p Pool) Option {
|
|
return func(o *vmOptions) {
|
|
pool, _ := p.(*pool)
|
|
o.pool = pool
|
|
}
|
|
}
|
|
|
|
func WithJsonnetBinary(jsonnetBinaryPath string) Option {
|
|
return func(o *vmOptions) {
|
|
o.jsonnetBinaryPath = jsonnetBinaryPath
|
|
}
|
|
}
|
|
|
|
func WithProcessArgs(args ...string) Option {
|
|
return func(o *vmOptions) {
|
|
o.args = args
|
|
}
|
|
}
|
|
|
|
func MakeSecureVM(opts ...Option) VM {
|
|
options := newVMOptions()
|
|
for _, o := range opts {
|
|
o(options)
|
|
}
|
|
|
|
if options.pool != nil {
|
|
return NewProcessPoolVM(options)
|
|
} else {
|
|
vm := jsonnet.MakeVM()
|
|
vm.Importer(new(ErrorImporter))
|
|
return vm
|
|
}
|
|
}
|
|
|
|
// ErrorImporter errors when calling "import".
|
|
type ErrorImporter struct{}
|
|
|
|
// Import fetches data from a map entry.
|
|
// All paths are treated as absolute keys.
|
|
func (importer *ErrorImporter) Import(importedFrom, importedPath string) (contents jsonnet.Contents, foundAt string, err error) {
|
|
return jsonnet.Contents{}, "", fmt.Errorf("import not available %v", importedPath)
|
|
}
|
|
|
|
func JsonnetTestBinary(t testing.TB) string {
|
|
t.Helper()
|
|
|
|
// We can force the usage of a given jsonnet executable.
|
|
// Useful to test different versions, or run the tests under wine.
|
|
if s := os.Getenv("ORY_JSONNET_PATH"); s != "" {
|
|
return s
|
|
}
|
|
|
|
var stderr bytes.Buffer
|
|
// Using `t.TempDir()` results in permissions errors on Windows, sometimes.
|
|
outPath := path.Join(os.TempDir(), "jsonnet")
|
|
if runtime.GOOS == "windows" {
|
|
outPath = outPath + ".exe"
|
|
}
|
|
cmd := exec.Command("go", "build", "-o", outPath, "github.com/ory/x/jsonnetsecure/cmd")
|
|
cmd.Stderr = &stderr
|
|
|
|
if err := cmd.Run(); err != nil || stderr.Len() != 0 {
|
|
t.Fatalf("building the Go binary returned error: %v\n%s", err, stderr.String())
|
|
}
|
|
|
|
return outPath
|
|
}
|