Skip to content

Commit

Permalink
Added URLGenerate and URLQueryFromJSON builtins for URL generation (o…
Browse files Browse the repository at this point in the history
…pen-policy-agent#766)

Add urlquery.encode_object to complement urlquery.encode

Signed-off-by: vrnmthr <[email protected]>
Signed-off-by: tsandall <[email protected]>
  • Loading branch information
vrnmthr authored and tsandall committed Jun 7, 2018
1 parent 9a6c7e9 commit 24dda01
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ast/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ var DefaultBuiltins = [...]*Builtin{
Base64UrlDecode,
URLQueryDecode,
URLQueryEncode,
URLQueryEncodeObject,
YAMLMarshal,
YAMLUnmarshal,

Expand Down Expand Up @@ -721,6 +722,15 @@ var URLQueryEncode = &Builtin{
),
}

// URLQueryEncodeObject encodes the given JSON into a URL encoded query string
var URLQueryEncodeObject = &Builtin{
Name: "urlquery.encode_object",
Decl: types.NewFunction(
types.Args(types.A),
types.S,
),
}

// YAMLMarshal serializes the input term.
var YAMLMarshal = &Builtin{
Name: "yaml.marshal",
Expand Down
39 changes: 39 additions & 0 deletions topdown/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,44 @@ func builtinURLQueryDecode(a ast.Value) (ast.Value, error) {
return ast.String(s), nil
}

func builtinURLQueryEncodeObject(a ast.Value) (ast.Value, error) {
asJSON, err := ast.JSON(a)
if err != nil {
return nil, err
}

// type assert on underlying structure
inputs, ok := asJSON.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("invalid JSON format")
}

query := url.Values{}

// loop over the inner items of the map, understanding what type they are
for k, v := range inputs {
switch vv := v.(type) {
case string:
// single value for a key
query.Set(k, vv)
case []interface{}:
// multiple values for the key, add all of them
for _, val := range vv {
strVal, ok := val.(string)
if !ok {
return nil, fmt.Errorf("only arrays of strings are permitted as values")
}
query.Add(k, strVal)
}
default:
}
}

// encoded version of these values
str := fmt.Sprintf("%v", query.Encode())
return ast.String(str), nil
}

func builtinYAMLMarshal(a ast.Value) (ast.Value, error) {

asJSON, err := ast.JSON(a)
Expand Down Expand Up @@ -176,6 +214,7 @@ func init() {
RegisterFunctionalBuiltin1(ast.Base64UrlDecode.Name, builtinBase64UrlDecode)
RegisterFunctionalBuiltin1(ast.URLQueryDecode.Name, builtinURLQueryDecode)
RegisterFunctionalBuiltin1(ast.URLQueryEncode.Name, builtinURLQueryEncode)
RegisterFunctionalBuiltin1(ast.URLQueryEncodeObject.Name, builtinURLQueryEncodeObject)
RegisterFunctionalBuiltin1(ast.YAMLMarshal.Name, builtinYAMLMarshal)
RegisterFunctionalBuiltin1(ast.YAMLUnmarshal.Name, builtinYAMLUnmarshal)
}

0 comments on commit 24dda01

Please sign in to comment.