mirror of https://github.com/daffainfo/nuclei.git
feat(template): allow custom type in metadata
In some case you may need to use custom type in `metadata`, like nested array or nested k-v: ```yaml info: metadata: components: - bootstrap - jquery ``` So this commit allowed use any custom type in `metadata`.dev
parent
c0932168ac
commit
03612a28b8
|
@ -57,7 +57,7 @@ type Info struct {
|
|||
// examples:
|
||||
// - value: >
|
||||
// map[string]string{"customField1":"customValue1"}
|
||||
Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty" jsonschema:"title=additional metadata for the template,description=Additional metadata fields for the template"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty" yaml:"metadata,omitempty" jsonschema:"title=additional metadata for the template,description=Additional metadata fields for the template"`
|
||||
|
||||
// description: |
|
||||
// Classification contains classification information about the template.
|
||||
|
|
|
@ -21,12 +21,19 @@ func TestInfoJsonMarshal(t *testing.T) {
|
|||
SeverityHolder: severity.Holder{Severity: severity.High},
|
||||
Tags: stringslice.StringSlice{Value: []string{"cve", "misc"}},
|
||||
Reference: stringslice.StringSlice{Value: "reference1"},
|
||||
Metadata: map[string]interface{}{
|
||||
"string_key": "string_value",
|
||||
"array_key": []string{"array_value1", "array_value2"},
|
||||
"map_key": map[string]string{
|
||||
"key1": "val1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := json.Marshal(&info)
|
||||
assert.Nil(t, err)
|
||||
|
||||
expected := `{"name":"Test Template Name","author":["forgedhallpass","ice3man"],"tags":["cve","misc"],"description":"Test description","reference":"reference1","severity":"high"}`
|
||||
expected := `{"name":"Test Template Name","author":["forgedhallpass","ice3man"],"tags":["cve","misc"],"description":"Test description","reference":"reference1","severity":"high","metadata":{"array_key":["array_value1","array_value2"],"map_key":{"key1":"val1"},"string_key":"string_value"}}`
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
||||
|
@ -38,6 +45,13 @@ func TestInfoYamlMarshal(t *testing.T) {
|
|||
SeverityHolder: severity.Holder{Severity: severity.High},
|
||||
Tags: stringslice.StringSlice{Value: []string{"cve", "misc"}},
|
||||
Reference: stringslice.StringSlice{Value: "reference1"},
|
||||
Metadata: map[string]interface{}{
|
||||
"string_key": "string_value",
|
||||
"array_key": []string{"array_value1", "array_value2"},
|
||||
"map_key": map[string]string{
|
||||
"key1": "val1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := yaml.Marshal(&info)
|
||||
|
@ -53,6 +67,13 @@ tags:
|
|||
description: Test description
|
||||
reference: reference1
|
||||
severity: high
|
||||
metadata:
|
||||
array_key:
|
||||
- array_value1
|
||||
- array_value2
|
||||
map_key:
|
||||
key1: val1
|
||||
string_key: string_value
|
||||
`
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
@ -66,7 +87,7 @@ func TestUnmarshal(t *testing.T) {
|
|||
dynamicKey1 := "customDynamicKey1"
|
||||
dynamicKey2 := "customDynamicKey2"
|
||||
|
||||
dynamicKeysMap := map[string]string{
|
||||
dynamicKeysMap := map[string]interface{}{
|
||||
dynamicKey1: "customDynamicValue1",
|
||||
dynamicKey2: "customDynamicValue2",
|
||||
}
|
||||
|
@ -92,8 +113,8 @@ func TestUnmarshal(t *testing.T) {
|
|||
severity: critical
|
||||
reference: ` + strings.Join(references, ", ") + `
|
||||
metadata:
|
||||
` + dynamicKey1 + `: ` + dynamicKeysMap[dynamicKey1] + `
|
||||
` + dynamicKey2 + `: ` + dynamicKeysMap[dynamicKey2] + `
|
||||
` + dynamicKey1 + `: ` + dynamicKeysMap[dynamicKey1].(string) + `
|
||||
` + dynamicKey2 + `: ` + dynamicKeysMap[dynamicKey2].(string) + `
|
||||
`
|
||||
yamlPayload2 := `
|
||||
name: ` + templateName + `
|
||||
|
@ -108,8 +129,8 @@ func TestUnmarshal(t *testing.T) {
|
|||
- ` + references[0] + ` # comments are not unmarshalled
|
||||
- ` + references[1] + `
|
||||
metadata:
|
||||
` + dynamicKey1 + `: ` + dynamicKeysMap[dynamicKey1] + `
|
||||
` + dynamicKey2 + `: ` + dynamicKeysMap[dynamicKey2] + `
|
||||
` + dynamicKey1 + `: ` + dynamicKeysMap[dynamicKey1].(string) + `
|
||||
` + dynamicKey2 + `: ` + dynamicKeysMap[dynamicKey2].(string) + `
|
||||
`
|
||||
|
||||
info1 := assertUnmarshalledTemplateInfo(t, yamlPayload1)
|
||||
|
|
|
@ -181,9 +181,12 @@ func ToMarkdownTableString(templateInfo *model.Info) string {
|
|||
builder := &bytes.Buffer{}
|
||||
|
||||
toMarkDownTable := func(insertionOrderedStringMap *utils.InsertionOrderedStringMap) {
|
||||
insertionOrderedStringMap.ForEach(func(key string, value string) {
|
||||
if utils.IsNotBlank(value) {
|
||||
builder.WriteString(fmt.Sprintf("| %s | %s |\n", key, value))
|
||||
insertionOrderedStringMap.ForEach(func(key string, value interface{}) {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
if utils.IsNotBlank(value.(string)) {
|
||||
builder.WriteString(fmt.Sprintf("| %s | %s |\n", key, value))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestToMarkdownTableString(t *testing.T) {
|
|||
SeverityHolder: severity.Holder{Severity: severity.High},
|
||||
Tags: stringslice.StringSlice{Value: []string{"cve", "misc"}},
|
||||
Reference: stringslice.StringSlice{Value: "reference1"},
|
||||
Metadata: map[string]string{
|
||||
Metadata: map[string]interface{}{
|
||||
"customDynamicKey1": "customDynamicValue1",
|
||||
"customDynamicKey2": "customDynamicValue2",
|
||||
},
|
||||
|
|
|
@ -2,17 +2,17 @@ package utils
|
|||
|
||||
type InsertionOrderedStringMap struct {
|
||||
keys []string `yaml:"-"`
|
||||
values map[string]string
|
||||
values map[string]interface{}
|
||||
}
|
||||
|
||||
func NewEmptyInsertionOrderedStringMap(size int) *InsertionOrderedStringMap {
|
||||
return &InsertionOrderedStringMap{
|
||||
keys: make([]string, 0, size),
|
||||
values: make(map[string]string, size),
|
||||
values: make(map[string]interface{}, size),
|
||||
}
|
||||
}
|
||||
|
||||
func NewInsertionOrderedStringMap(stringMap map[string]string) *InsertionOrderedStringMap {
|
||||
func NewInsertionOrderedStringMap(stringMap map[string]interface{}) *InsertionOrderedStringMap {
|
||||
result := NewEmptyInsertionOrderedStringMap(len(stringMap))
|
||||
|
||||
for k, v := range stringMap {
|
||||
|
@ -22,13 +22,13 @@ func NewInsertionOrderedStringMap(stringMap map[string]string) *InsertionOrdered
|
|||
return result
|
||||
}
|
||||
|
||||
func (insertionOrderedStringMap *InsertionOrderedStringMap) ForEach(fn func(key string, data string)) {
|
||||
func (insertionOrderedStringMap *InsertionOrderedStringMap) ForEach(fn func(key string, data interface{})) {
|
||||
for _, key := range insertionOrderedStringMap.keys {
|
||||
fn(key, insertionOrderedStringMap.values[key])
|
||||
}
|
||||
}
|
||||
|
||||
func (insertionOrderedStringMap *InsertionOrderedStringMap) Set(key string, value string) {
|
||||
func (insertionOrderedStringMap *InsertionOrderedStringMap) Set(key string, value interface{}) {
|
||||
_, present := insertionOrderedStringMap.values[key]
|
||||
insertionOrderedStringMap.values[key] = value
|
||||
if !present {
|
||||
|
|
Loading…
Reference in New Issue