Merge pull request #337 from moorereason/iss333

Update GetParameter to support keys with dots
This commit is contained in:
Adnan Hajdarević 2019-09-18 18:02:25 +02:00 committed by GitHub
commit ffba396523
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 24 deletions

View file

@ -162,7 +162,6 @@ func CheckScalrSignature(headers map[string]interface{}, body []byte, signingKey
}
// Example format: Fri 08 Sep 2017 11:24:32 UTC
date, err := time.Parse("Mon 02 Jan 2006 15:04:05 MST", dateHeader)
//date, err := time.Parse(time.RFC1123, dateHeader)
if err != nil {
return false, err
}
@ -185,6 +184,7 @@ func CheckIPWhitelist(remoteAddr string, ipRange string) (bool, error) {
if i := strings.LastIndex(ip, ":"); i != -1 {
ip = ip[:i]
ip = strings.Trim(ip, " []")
}
parsedIP := net.ParseIP(ip)
@ -222,7 +222,6 @@ func ReplaceParameter(s string, params interface{}, value interface{}) bool {
if paramsValue := reflect.ValueOf(params); paramsValue.Kind() == reflect.Slice {
if paramsValueSliceLength := paramsValue.Len(); paramsValueSliceLength > 0 {
if p := strings.SplitN(s, ".", 2); len(p) > 1 {
index, err := strconv.ParseUint(p[0], 10, 64)
@ -257,8 +256,12 @@ func GetParameter(s string, params interface{}) (interface{}, bool) {
return nil, false
}
if paramsValue := reflect.ValueOf(params); paramsValue.Kind() == reflect.Slice {
if paramsValueSliceLength := paramsValue.Len(); paramsValueSliceLength > 0 {
paramsValue := reflect.ValueOf(params)
switch paramsValue.Kind() {
case reflect.Slice:
paramsValueSliceLength := paramsValue.Len()
if paramsValueSliceLength > 0 {
if p := strings.SplitN(s, ".", 2); len(p) > 1 {
index, err := strconv.ParseUint(p[0], 10, 64)
@ -280,18 +283,20 @@ func GetParameter(s string, params interface{}) (interface{}, bool) {
}
return nil, false
}
if p := strings.SplitN(s, ".", 2); len(p) > 1 {
if paramsValue := reflect.ValueOf(params); paramsValue.Kind() == reflect.Map {
if pValue, ok := params.(map[string]interface{})[p[0]]; ok {
case reflect.Map:
// Check for raw key
if v, ok := params.(map[string]interface{})[s]; ok {
return v, true
}
// Checked for dotted references
p := strings.SplitN(s, ".", 2)
if pValue, ok := params.(map[string]interface{})[p[0]]; ok {
if len(p) > 1 {
return GetParameter(p[1], pValue)
}
} else {
return nil, false
}
} else {
if pValue, ok := params.(map[string]interface{})[p[0]]; ok {
return pValue, true
}
}
@ -334,7 +339,6 @@ func (ha *Argument) Get(headers, query, payload *map[string]interface{}) (string
return ha.Name, true
case SourceEntirePayload:
r, err := json.Marshal(payload)
if err != nil {
return "", false
}
@ -342,7 +346,6 @@ func (ha *Argument) Get(headers, query, payload *map[string]interface{}) (string
return string(r), true
case SourceEntireHeaders:
r, err := json.Marshal(headers)
if err != nil {
return "", false
}
@ -350,7 +353,6 @@ func (ha *Argument) Get(headers, query, payload *map[string]interface{}) (string
return string(r), true
case SourceEntireQuery:
r, err := json.Marshal(query)
if err != nil {
return "", false
}
@ -440,7 +442,7 @@ type Hook struct {
// ParseJSONParameters decodes specified arguments to JSON objects and replaces the
// string with the newly created object
func (h *Hook) ParseJSONParameters(headers, query, payload *map[string]interface{}) []error {
var errors = make([]error, 0)
errors := make([]error, 0)
for i := range h.JSONStringParameters {
if arg, ok := h.JSONStringParameters[i].Get(headers, query, payload); ok {
@ -450,7 +452,6 @@ func (h *Hook) ParseJSONParameters(headers, query, payload *map[string]interface
decoder.UseNumber()
err := decoder.Decode(&newArg)
if err != nil {
errors = append(errors, &ParseError{err})
continue
@ -493,8 +494,8 @@ func (h *Hook) ParseJSONParameters(headers, query, payload *map[string]interface
// ExtractCommandArguments creates a list of arguments, based on the
// PassArgumentsToCommand property that is ready to be used with exec.Command()
func (h *Hook) ExtractCommandArguments(headers, query, payload *map[string]interface{}) ([]string, []error) {
var args = make([]string, 0)
var errors = make([]error, 0)
args := make([]string, 0)
errors := make([]error, 0)
args = append(args, h.ExecuteCommand)
@ -518,8 +519,8 @@ func (h *Hook) ExtractCommandArguments(headers, query, payload *map[string]inter
// format, based on the PassEnvironmentToCommand property that is ready to be used
// with exec.Command().
func (h *Hook) ExtractCommandArgumentsForEnv(headers, query, payload *map[string]interface{}) ([]string, []error) {
var args = make([]string, 0)
var errors = make([]error, 0)
args := make([]string, 0)
errors := make([]error, 0)
for i := range h.PassEnvironmentToCommand {
if arg, ok := h.PassEnvironmentToCommand[i].Get(headers, query, payload); ok {
if h.PassEnvironmentToCommand[i].EnvName != "" {
@ -552,8 +553,8 @@ type FileParameter struct {
// format, based on the PassFileToCommand property that is ready to be used
// with exec.Command().
func (h *Hook) ExtractCommandArgumentsForFile(headers, query, payload *map[string]interface{}) ([]FileParameter, []error) {
var args = make([]FileParameter, 0)
var errors = make([]error, 0)
args := make([]FileParameter, 0)
errors := make([]error, 0)
for i := range h.PassFileToCommand {
if arg, ok := h.PassFileToCommand[i].Get(headers, query, payload); ok {

View file

@ -7,6 +7,38 @@ import (
"testing"
)
func TestGetParameter(t *testing.T) {
for _, test := range []struct {
key string
val interface{}
expect interface{}
ok bool
}{
// True
{"a", map[string]interface{}{"a": "1"}, "1", true},
{"a.b", map[string]interface{}{"a.b": "1"}, "1", true},
{"a.c", map[string]interface{}{"a": map[string]interface{}{"c": 2}}, 2, true},
{"a.1", map[string]interface{}{"a": map[string]interface{}{"1": 3}}, 3, true},
{"a.1", map[string]interface{}{"a": []interface{}{"a", "b"}}, "b", true},
{"0", []interface{}{"a", "b"}, "a", true},
// False
{"z", map[string]interface{}{"a": "1"}, nil, false},
{"a.z", map[string]interface{}{"a": map[string]interface{}{"b": 2}}, nil, false},
{"z.b", map[string]interface{}{"a": map[string]interface{}{"z": 2}}, nil, false},
{"a.2", map[string]interface{}{"a": []interface{}{"a", "b"}}, nil, false},
} {
res, ok := GetParameter(test.key, test.val)
if ok != test.ok {
t.Errorf("unexpected result given {%q, %q}: %t\n", test.key, test.val, ok)
}
if !reflect.DeepEqual(res, test.expect) {
t.Errorf("failed given {%q, %q}:\nexpected {%#v}\ngot {%#v}\n", test.key, test.val, test.expect, res)
}
}
}
var checkPayloadSignatureTests = []struct {
payload []byte
secret string