github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/transform/startf/sandbox.go (about)

     1  package startf
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  
     8  	starhttp "github.com/qri-io/starlib/http"
     9  	"github.com/qri-io/starlib/util"
    10  	"go.starlark.net/starlark"
    11  )
    12  
    13  var (
    14  	httpGuard = &HTTPGuard{NetworkEnabled: true}
    15  	// ErrNtwkDisabled is returned whenever a network call is attempted but h.NetworkEnabled is false
    16  	ErrNtwkDisabled = fmt.Errorf("network use is disabled. http can only be used during download step")
    17  )
    18  
    19  // HTTPGuard protects network requests, only allowing when network is enabled
    20  type HTTPGuard struct {
    21  	NetworkEnabled bool
    22  }
    23  
    24  // Allowed implements starlib/http RequestGuard
    25  func (h *HTTPGuard) Allowed(_ *starlark.Thread, req *http.Request) (*http.Request, error) {
    26  	if !h.NetworkEnabled {
    27  		return nil, ErrNtwkDisabled
    28  	}
    29  	return req, nil
    30  }
    31  
    32  // EnableNtwk allows network calls
    33  func (h *HTTPGuard) EnableNtwk() {
    34  	h.NetworkEnabled = true
    35  }
    36  
    37  // DisableNtwk prevents network calls from succeeding
    38  func (h *HTTPGuard) DisableNtwk() {
    39  	h.NetworkEnabled = false
    40  }
    41  
    42  func init() {
    43  	// connect httpGuard instance to starlib http guard
    44  	starhttp.Guard = httpGuard
    45  }
    46  
    47  type config map[string]interface{}
    48  
    49  var (
    50  	_ starlark.Value    = (*config)(nil)
    51  	_ starlark.HasAttrs = (*config)(nil)
    52  )
    53  
    54  func (c config) Type() string          { return "config" }
    55  func (c config) String() string        { return mapStringRepr(c) }
    56  func (c config) Freeze()               {} // noop
    57  func (c config) Truth() starlark.Bool  { return starlark.True }
    58  func (c config) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", c.Type()) }
    59  
    60  func (c config) AttrNames() []string { return []string{"get"} }
    61  func (c config) Attr(s string) (starlark.Value, error) {
    62  	if s == "get" {
    63  		return starlark.NewBuiltin("get", configGet).BindReceiver(c), nil
    64  	}
    65  	return nil, nil
    66  }
    67  
    68  func configGet(_ *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
    69  	var (
    70  		self = b.Receiver().(config)
    71  		key  string
    72  		def  starlark.Value
    73  	)
    74  	if err := starlark.UnpackPositionalArgs("get", args, kwargs, 1, &key, &def); err != nil {
    75  		return starlark.None, err
    76  	}
    77  
    78  	v, ok := self[key]
    79  	if !ok {
    80  		if def != nil {
    81  			return def, nil
    82  		}
    83  		return starlark.None, nil
    84  	}
    85  	return util.Marshal(v)
    86  }
    87  
    88  type secrets = config
    89  
    90  func mapStringRepr(m map[string]interface{}) string {
    91  	builder := strings.Builder{}
    92  	builder.WriteString("{ ")
    93  	i := 0
    94  	for k, v := range m {
    95  		i++
    96  		if i == len(m) {
    97  			builder.WriteString(fmt.Sprintf("%s: %v ", k, v))
    98  			break
    99  		}
   100  		builder.WriteString(fmt.Sprintf("%s: %v, ", k, v))
   101  	}
   102  	builder.WriteString("}")
   103  	return builder.String()
   104  }