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  }