-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Protector): stepped transform functions, protected execution
after a chat with @dustmop we came to the conclusion that we need more control over what kind of things the user can do and when they can do them in the context of a transformation. The first example we could think of is preventing a transform script that lists a peers datasets & posting them to a random server with the http module. To solve this we're restructuring the execution of transform steps as a set of functions with standard names that the user can declare, and we will call. The stipulation is the output of each of these fuctions can only be data. Each of these opt-in "steps" execute in a predeclared order, with the result of the previous step being the input to the next step. The input to the initial step is any provided dataset data.
- Loading branch information
Showing
8 changed files
with
261 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
load('qri.sky', 'qri') | ||
|
||
cfg = qri.get_config() | ||
|
||
qri.commit([1,2,3,4,5,6]) | ||
cfg = qri.get_config() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package skytf | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/google/skylark" | ||
"github.com/google/skylark/skylarkstruct" | ||
) | ||
|
||
// Protector wraps a skylark module with a set of rules that control when a module method can be called | ||
type Protector struct { | ||
step string | ||
Module string | ||
Rules []Rule | ||
} | ||
|
||
// Rule allows or denies the execution of a method in a step | ||
// empty string functions as a wildcard / match all, for example: | ||
// Rule{"", "", true} // allow all methods to execute on all steps | ||
// Rule{"", "", false} // deny all methods to execute on all steps | ||
// Rule{"foo", "bar", true} // allow method "bar" in step "foo" | ||
// Rule{"foo", "", true} // allow all methods in step "foo" | ||
type Rule struct { | ||
Step, Method string | ||
Allow bool | ||
} | ||
|
||
// SetStep updates the current step of execution | ||
func (p *Protector) SetStep(step string) { | ||
p.step = step | ||
} | ||
|
||
// NewProtectedBuiltin wraps a builtin method with a rules check | ||
func (p *Protector) NewProtectedBuiltin(name string, fn *skylark.Builtin) *skylark.Builtin { | ||
protected := func(thread *skylark.Thread, bi *skylark.Builtin, args skylark.Tuple, kwargs []skylark.Tuple) (skylark.Value, error) { | ||
if !p.allowed(name) { | ||
return nil, fmt.Errorf("%s.%s cannot be called in %s step", p.Module, name, p.step) | ||
} | ||
return fn.Call(thread, args, kwargs) | ||
} | ||
return skylark.NewBuiltin(name, protected) | ||
} | ||
|
||
func (p *Protector) allowed(method string) (allowed bool) { | ||
for _, r := range p.Rules { | ||
if (r.Step == "" || p.step == r.Step) && (r.Method == "" || r.Method == method) { | ||
allowed = r.Allow | ||
} | ||
} | ||
return | ||
} | ||
|
||
// ProtectMethods wraps an input StringDict with protector funcs | ||
func (p *Protector) ProtectMethods(dict skylark.StringDict) { | ||
for key, x := range dict { | ||
switch x.Type() { | ||
case "struct": | ||
if st, ok := x.(*skylarkstruct.Struct); ok { | ||
d := skylark.StringDict{} | ||
st.ToStringDict(d) | ||
p.ProtectMethods(d) | ||
dict[key] = skylarkstruct.FromStringDict(skylarkstruct.Default, d) | ||
} else { | ||
panic("skylark value claimed to be a struct but wasn't a function pointer") | ||
} | ||
case "builtin_function_or_method": | ||
if bi, ok := x.(*skylark.Builtin); ok { | ||
dict[key] = p.NewProtectedBuiltin(key, bi) | ||
} else { | ||
panic("skylark value claimed to be a builtin but wasn't a function pointer") | ||
} | ||
// case "function": | ||
// if fn, ok := x.(*skylark.Function); ok { | ||
// fmt.Printf("protecting: %s.%s", p.Module, key) | ||
// dict[key] = p.NewProtectedBuiltin(key, fn) | ||
// } else { | ||
// panic("skylark value claimed to be a function but wasn't a function pointer") | ||
// } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
load('qri.sky', 'qri') | ||
load('http.sky', 'http') | ||
|
||
res = http.get_json('https://api.github.com/repos/qri-io/qri/releases') | ||
|
||
qri.commit(res[0]['assets']) | ||
def download(data): | ||
res = http.get_json('https://api.github.com/repos/qri-io/qri/releases') | ||
return res[0]['assets'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
load('qri.sky', 'qri') | ||
qri.commit([1, 1.5, False, 'a','b','c', { "a" : 1, "b" : True }, [1,2]]) | ||
|
||
def transform(data): | ||
return [1, 1.5, False, 'a','b','c', { "a" : 1, "b" : True }, [1,2]] |
Oops, something went wrong.