Skip to content

Commit

Permalink
Support recursive descent in JSONPath(s) (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
M. Mert Yıldıran authored Jun 6, 2022
1 parent e8e9d13 commit 8ef17f1
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
4 changes: 2 additions & 2 deletions server/lib/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ func redactXml(obj interface{}, path string) (xmlValue []byte, err error) {
func redactRecursively(obj interface{}, paths []string) (newObj interface{}, err error) {
newObj = obj
for i, path := range paths {
xmlPaths := strings.Split(path, ".xml().")
xmlPaths := strings.Split(path, ".xml()")

var jsonPath jp.Expr
jsonPath, err = jp.ParseString(xmlPaths[0])
Expand Down Expand Up @@ -526,7 +526,7 @@ func redactRecursively(obj interface{}, paths []string) (newObj interface{}, err
func redact(args ...interface{}) (interface{}, interface{}) {
obj := args[0]
for _, param := range args[2:] {
paths := strings.Split(stringOperand(param), ".json().")
paths := strings.Split(stringOperand(param), ".json()")
var err error
obj, err = redactRecursively(obj, paths)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions server/lib/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ var data = []struct {
{`response.body.json()["model"] == "Camaro"`, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, true, 0, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`},
{`response.body.json()["model"] == "CamaroX"`, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, false, 0, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`},
{`response.body.json().brand.name == "Chevrolet"`, `{"response":{"body":"eyJpZCI6MTE0OTA1LCJtb2RlbCI6IkNhbWFybyIsImJyYW5kIjp7Im5hbWUiOiJDaGV2cm9sZXQifSwieWVhciI6MjAyMX0="}}`, true, 0, `{"response":{"body":"eyJpZCI6MTE0OTA1LCJtb2RlbCI6IkNhbWFybyIsImJyYW5kIjp7Im5hbWUiOiJDaGV2cm9sZXQifSwieWVhciI6MjAyMX0="}}`},
{`response.body.json()..name == "Chevrolet"`, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, true, 0, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`},
{`response.body.json()..model == "Camaro"`, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, true, 0, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`},
{`response.body.json()..surname == "Chevrolet"`, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, false, 0, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`},
{`id == 114905 and redact("model", "brand.name")`, `{"id":114905,"model":"Camaro","brand":{"name":"Chevrolet"},"year":2021}`, true, 0, fmt.Sprintf(`{"id":114905,"model":"%s","brand":{"name":"%s"},"year":2021}`, REDACTED, REDACTED)},
{`id == 114905 and redact("modelx", "brand.name")`, `{"id":114905,"model":"Camaro","brand":{"name":"Chevrolet"},"year":2021}`, true, 0, fmt.Sprintf(`{"id":114905,"model":"Camaro","brand":{"name":"%s"},"year":2021}`, REDACTED)},
{`id == 114906 and redact("model", "brand.name")`, `{"id":114905,"model":"Camaro","brand":{"name":"Chevrolet"},"year":2021}`, false, 0, `{"id":114905,"model":"Camaro","brand":{"name":"Chevrolet"},"year":2021}`},
Expand Down Expand Up @@ -223,6 +226,10 @@ var dataRedact = []struct {
strCompare bool
}{
{`redact("response.body.json().model")`, true, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, fmt.Sprintf(`{"id":114905,"model":"%s","brand":{"name":"Chevrolet"},"year":2021}`, REDACTED), false},
{`redact("response.body.json()..name")`, true, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, fmt.Sprintf(`{"id":114905,"model":"Camaro","brand":{"name":"%s"},"year":2021}`, REDACTED), false},
{`redact("response.body.json()...name")`, true, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, fmt.Sprintf(`{"id":114905,"model":"Camaro","brand":{"name":"%s"},"year":2021}`, REDACTED), false},
{`redact("response.body.json()..surname")`, true, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, `{"id":114905,"model":"Camaro","brand":{"name":"Chevrolet"},"year":2021}`, false},
{`redact("response.body.json()...surname")`, true, `{"response":{"body":"{\"id\":114905,\"model\":\"Camaro\",\"brand\":{\"name\":\"Chevrolet\"},\"year\":2021}"}}`, `{"id":114905,"model":"Camaro","brand":{"name":"Chevrolet"},"year":2021}`, false},
{`redact("response.body.json().model")`, true, `{"response":{"body":"eyJpZCI6MTE0OTA1LCJtb2RlbCI6IkNhbWFybyIsImJyYW5kIjp7Im5hbWUiOiJDaGV2cm9sZXQifSwieWVhciI6MjAyMX0="}}`, `eyJpZCI6MTE0OTA1LCJtb2RlbCI6IltSRURBQ1RFRF0iLCJicmFuZCI6eyJuYW1lIjoiQ2hldnJvbGV0In0sInllYXIiOjIwMjF9`, false},
{`redact("response.body.xml().bookstore.book[1].title")`, true, `{"response":{"body":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<bookstore><book category=\"cooking\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category=\"children\"><title lang=\"en\">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category=\"web\"><title lang=\"en\">XQuery Kick Start</title><author>James McGovern</author><author>Per Bothner</author><author>Kurt Cagle</author><author>James Linn</author><author>Vaidyanathan Nagarajan</author><year>2003</year><price>49.99</price></book><book category=\"web\"><title lang=\"en\">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book></bookstore>\r\n"}}`, `<?xml version="1.0" encoding="UTF-8"?>
<bookstore><book category="cooking"><author>Giada De Laurentiis</author><price>30.00</price><title lang="en">Everyday Italian</title><year>2005</year></book><book category="children"><author>J K. Rowling</author><price>29.99</price><title>[REDACTED]</title><year>2005</year></book><book category="web"><author>James McGovern</author><author>Per Bothner</author><author>Kurt Cagle</author><author>James Linn</author><author>Vaidyanathan Nagarajan</author><price>49.99</price><title lang="en">XQuery Kick Start</title><year>2003</year></book><book category="web"><author>Erik T. Ray</author><price>39.95</price><title lang="en">Learning XML</title><year>2003</year></book></bookstore>`, true},
Expand Down
7 changes: 4 additions & 3 deletions server/lib/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ type CallExpression struct {
}

type SelectExpression struct {
Index *int `[ "[" @Int "]" ]`
Key *string `[ "[" @(String|Char|RawString|"*") "]" ]`
Expression *Expression `[ "." @@ ]`
Index *int `[ "[" @Int "]" ]`
Key *string `[ "[" @(String|Char|RawString|"*") "]" ]`
RecursiveDescent *string `[ "." "." @Ident ]`
Expression *Expression `[ "." @@ ]`
}

type Parameter struct {
Expand Down
7 changes: 7 additions & 0 deletions server/lib/precompute.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ func computeCallExpression(call *CallExpression, prependPath string, jsonHelperP
prop.Limit = _prop.Limit
return
}

// `request.body.json()..name` goes here
if call.SelectExpression.RecursiveDescent != nil {
if jsonHelperUsed {
prop.Path = fmt.Sprintf("..%s", *call.SelectExpression.RecursiveDescent)
}
}
}
} else {
// It's a function call
Expand Down

0 comments on commit 8ef17f1

Please sign in to comment.