Skip to content

Commit

Permalink
Add support for YAML encoded input values
Browse files Browse the repository at this point in the history
These changes add support or YAML encoded input values in the V1 Data API.

Fixes #290

Signed-off-by: repenno <rapenno@gmail.com>
  • Loading branch information
BenderScript authored and tsandall committed Oct 15, 2018
1 parent 277abcf commit 843e64f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
16 changes: 12 additions & 4 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ func (s *Server) v1DataPost(w http.ResponseWriter, r *http.Request) {

m.Timer(metrics.RegoQueryParse).Start()

input, err := readInputPostV1(r.Body)
input, err := readInputPostV1(r)
if err != nil {
writer.ErrorString(w, http.StatusBadRequest, types.CodeInvalidParameter, err)
return
Expand Down Expand Up @@ -1756,19 +1756,27 @@ func readInputGetV1(str string) (ast.Value, error) {
return ast.InterfaceToValue(input)
}

func readInputPostV1(r io.ReadCloser) (ast.Value, error) {
func readInputPostV1(r *http.Request) (ast.Value, error) {

bs, err := ioutil.ReadAll(r)
bs, err := ioutil.ReadAll(r.Body)

if err != nil {
return nil, err
}

if len(bs) > 0 {

ct := r.Header.Get("Content-Type")

var request types.DataRequestV1

if err := util.UnmarshalJSON(bs, &request); err != nil {
// There is no standard for yaml mime-type so we just look for
// anything related
if strings.Contains(ct, "yaml") {
if err := util.Unmarshal(bs, &request); err != nil {
return nil, errors.Wrapf(err, "body contains malformed input document")
}
} else if err := util.UnmarshalJSON(bs, &request); err != nil {
return nil, errors.Wrapf(err, "body contains malformed input document")
}

Expand Down
38 changes: 38 additions & 0 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,44 @@ p = true { false }`
}
}

func TestDataPostInputV1Yaml(t *testing.T) {

testMod1 := `package testmod
import input.req1
import input.req2 as reqx
import input.req3.attr1
p[x] { q[x]; not r[x] }
q[x] { data.x.y[i] = x }
r[x] { data.x.z[i] = x }
g = true { req1.a[0] = 1; reqx.b[i] = 1 }
h = true { attr1[i] > 1 }
gt1 = true { req1 > 1 }
arr = [1, 2, 3, 4] { true }
undef = true { false }`

inputYaml := `
---
input:
req1: 2`

f := newFixture(t)
if err := f.v1(http.MethodPut, "/policies/test", testMod1, 200, ""); err != nil {
t.Fatalf("Unexpected error from PUT /policies/test: %v", err)
}
// First JSON and then later yaml to make sure both work
if err := f.v1(http.MethodPost, "/data/testmod/gt1", `{"input": {"req1": 2}}`, 200, `{"result": true}`); err != nil {
t.Fatalf("Unexpected error from PUT /policies/test: %v", err)
}
req := newReqV1(http.MethodPost, "/data/testmod/gt1", inputYaml)
// There is no standard for yaml mime-type
req.Header.Set("Content-Type", "application/x-yaml")
if err := f.executeRequest(req, 200, `{"result": true}`); err != nil {
t.Fatalf("Unexpected error from POST with yaml: %v", err)
}
}

func TestDataPutV1IfNoneMatch(t *testing.T) {
f := newFixture(t)
if err := f.v1(http.MethodPut, "/data/a/b/c", "0", 204, ""); err != nil {
Expand Down

0 comments on commit 843e64f

Please sign in to comment.