github.com/crowdsecurity/crowdsec@v1.6.1/pkg/exprhelpers/jsonextract.go (about) 1 package exprhelpers 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "strings" 8 9 "github.com/buger/jsonparser" 10 11 log "github.com/sirupsen/logrus" 12 ) 13 14 // func JsonExtractLib(jsblob string, target ...string) string { 15 func JsonExtractLib(params ...any) (any, error) { 16 jsblob := params[0].(string) 17 target := params[1].([]string) 18 value, dataType, _, err := jsonparser.Get( 19 jsonparser.StringToBytes(jsblob), 20 target..., 21 ) 22 23 if err != nil { 24 if errors.Is(err, jsonparser.KeyPathNotFoundError) { 25 log.Debugf("%+v doesn't exist", target) 26 return "", nil 27 } 28 log.Errorf("jsonExtractLib : %+v : %s", target, err) 29 return "", nil 30 } 31 if dataType == jsonparser.NotExist { 32 log.Debugf("%+v doesn't exist", target) 33 return "", nil 34 } 35 strvalue := string(value) 36 return strvalue, nil 37 } 38 39 // func JsonExtractUnescape(jsblob string, target ...string) string { 40 func JsonExtractUnescape(params ...any) (any, error) { 41 var value string 42 var err error 43 jsblob := params[0].(string) 44 switch v := params[1].(type) { 45 case string: 46 target := v 47 value, err = jsonparser.GetString( 48 jsonparser.StringToBytes(jsblob), 49 target, 50 ) 51 case []string: 52 target := v 53 value, err = jsonparser.GetString( 54 jsonparser.StringToBytes(jsblob), 55 target..., 56 ) 57 } 58 59 if err != nil { 60 if errors.Is(err, jsonparser.KeyPathNotFoundError) { 61 log.Debugf("%+v doesn't exist", params[1]) 62 return "", nil 63 } 64 log.Errorf("JsonExtractUnescape : %+v : %s", params[1], err) 65 return "", nil 66 } 67 log.Tracef("extract path %+v", params[1]) 68 return value, nil 69 } 70 71 // func JsonExtract(jsblob string, target string) string { 72 func JsonExtract(params ...any) (any, error) { 73 jsblob := params[0].(string) 74 target := params[1].(string) 75 if !strings.HasPrefix(target, "[") { 76 target = strings.ReplaceAll(target, "[", ".[") 77 } 78 fullpath := strings.Split(target, ".") 79 80 log.Tracef("extract path %+v", fullpath) 81 return JsonExtractLib(jsblob, fullpath) 82 } 83 84 func jsonExtractType(jsblob string, target string, t jsonparser.ValueType) ([]byte, error) { 85 if !strings.HasPrefix(target, "[") { 86 target = strings.ReplaceAll(target, "[", ".[") 87 } 88 fullpath := strings.Split(target, ".") 89 90 log.Tracef("extract path %+v", fullpath) 91 92 value, dataType, _, err := jsonparser.Get( 93 jsonparser.StringToBytes(jsblob), 94 fullpath..., 95 ) 96 97 if err != nil { 98 if errors.Is(err, jsonparser.KeyPathNotFoundError) { 99 log.Debugf("Key %+v doesn't exist", target) 100 return nil, fmt.Errorf("key %s does not exist", target) 101 } 102 log.Errorf("jsonExtractType : %s : %s", target, err) 103 return nil, fmt.Errorf("jsonExtractType: %s : %w", target, err) 104 } 105 106 if dataType != t { 107 log.Errorf("jsonExtractType : expected type %s for target %s but found %s", t, target, dataType.String()) 108 return nil, fmt.Errorf("jsonExtractType: expected type %s for target %s but found %s", t, target, dataType.String()) 109 } 110 111 return value, nil 112 } 113 114 // func JsonExtractSlice(jsblob string, target string) []interface{} { 115 func JsonExtractSlice(params ...any) (any, error) { 116 jsblob := params[0].(string) 117 target := params[1].(string) 118 value, err := jsonExtractType(jsblob, target, jsonparser.Array) 119 120 if err != nil { 121 log.Errorf("JsonExtractSlice : %s", err) 122 return []interface{}(nil), nil 123 } 124 125 s := make([]interface{}, 0) 126 127 err = json.Unmarshal(value, &s) 128 if err != nil { 129 log.Errorf("JsonExtractSlice: could not convert '%s' to slice: %s", value, err) 130 return []interface{}(nil), nil 131 } 132 return s, nil 133 } 134 135 // func JsonExtractObject(jsblob string, target string) map[string]interface{} { 136 func JsonExtractObject(params ...any) (any, error) { 137 jsblob := params[0].(string) 138 target := params[1].(string) 139 value, err := jsonExtractType(jsblob, target, jsonparser.Object) 140 141 if err != nil { 142 log.Errorf("JsonExtractObject: %s", err) 143 return map[string]interface{}(nil), nil 144 } 145 146 s := make(map[string]interface{}) 147 148 err = json.Unmarshal(value, &s) 149 if err != nil { 150 log.Errorf("JsonExtractObject: could not convert '%s' to map[string]interface{}: %s", value, err) 151 return map[string]interface{}(nil), nil 152 } 153 return s, nil 154 } 155 156 // func ToJson(obj interface{}) string { 157 func ToJson(params ...any) (any, error) { 158 obj := params[0] 159 b, err := json.Marshal(obj) 160 if err != nil { 161 log.Errorf("ToJson : %s", err) 162 return "", nil 163 } 164 return string(b), nil 165 } 166 167 // Func UnmarshalJSON(jsonBlob []byte, target interface{}) error { 168 func UnmarshalJSON(params ...any) (any, error) { 169 jsonBlob := params[0].(string) 170 target := params[1].(map[string]interface{}) 171 key := params[2].(string) 172 173 var out interface{} 174 175 err := json.Unmarshal([]byte(jsonBlob), &out) 176 if err != nil { 177 log.WithField("line", jsonBlob).Errorf("UnmarshalJSON : %s", err) 178 return nil, err 179 } 180 target[key] = out 181 return nil, nil 182 }