From 16cefcc55e10c67a5d4deda299540b4b174880d0 Mon Sep 17 00:00:00 2001 From: Andrey Pokhilko Date: Mon, 21 Feb 2022 15:03:32 +0300 Subject: [PATCH] Figure out decimal pattern --- agent/pkg/oas/tree.go | 63 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/agent/pkg/oas/tree.go b/agent/pkg/oas/tree.go index 81ed6d778..f2e464bee 100644 --- a/agent/pkg/oas/tree.go +++ b/agent/pkg/oas/tree.go @@ -1,7 +1,9 @@ package oas import ( + "encoding/json" "net/url" + "regexp" "strconv" "strings" @@ -50,7 +52,7 @@ func (n *Node) getOrSet(path NodePath, existingPathObj *openapi.PathObj) (node * } if node == nil { - node = n.searchInParams(paramObj, chunkIsGibberish) + node = n.searchInParams(paramObj, pathChunk, chunkIsGibberish) } // still no node found, should create it @@ -76,6 +78,10 @@ func (n *Node) getOrSet(path NodePath, existingPathObj *openapi.PathObj) (node * if err != nil { logger.Log.Warningf("Failed to add example to a parameter: %s", err) } + + if len(*exmp) > 1 && node.pathParam.Schema.Pattern == nil { // is it enough to decide on 2 samples? + node.pathParam.Schema.Pattern = getPatternFromExamples(exmp) + } } // TODO: eat up trailing slash, in a smart way: node.pathObj!=nil && path[1]=="" @@ -88,6 +94,34 @@ func (n *Node) getOrSet(path NodePath, existingPathObj *openapi.PathObj) (node * return node } +func getPatternFromExamples(exmp *openapi.Examples) *openapi.Regexp { + allInts := true + for _, example := range *exmp { + exampleObj, err := example.ResolveExample(exampleResolver) + if err != nil { + continue + } + + var value string + err = json.Unmarshal(exampleObj.Value, &value) + if err != nil { + logger.Log.Warningf("Failed decoding parameter example into string: %s", err) + continue + } + + if _, err := strconv.Atoi(value); err != nil { + allInts = false + } + } + + if allInts { + re := new(openapi.Regexp) + re.Regexp = regexp.MustCompile("\\d+") + return re + } + return nil +} + func (n *Node) createParam() *openapi.ParameterObj { name := "param" @@ -118,20 +152,25 @@ func (n *Node) createParam() *openapi.ParameterObj { return newParam } -func (n *Node) searchInParams(paramObj *openapi.ParameterObj, chunkIsGibberish bool) *Node { - // look among params +func (n *Node) searchInParams(paramObj *openapi.ParameterObj, chunk string, chunkIsGibberish bool) *Node { if paramObj != nil || chunkIsGibberish { - for _, subnode := range n.children { - if subnode.constant != nil { - continue - } + logger.Log.Debugf("") + } - // TODO: check the regex pattern of param? for exceptions etc + // look among params + for _, subnode := range n.children { + if subnode.constant != nil { + continue + } - if paramObj != nil { - // TODO: mergeParam(subnode.pathParam, paramObj) - return subnode - } else { + if chunkIsGibberish { + return subnode + } else if paramObj != nil { + // TODO: mergeParam(subnode.pathParam, paramObj) + return subnode + } else if subnode.pathParam.Schema.Pattern != nil { + // TODO: and not in exceptions + if subnode.pathParam.Schema.Pattern.Match([]byte(chunk)) { return subnode } }