diff --git a/hook/hook.go b/hook/hook.go index 4d6be14..98fb975 100644 --- a/hook/hook.go +++ b/hook/hook.go @@ -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 } } diff --git a/hook/hook_test.go b/hook/hook_test.go index e6bfce2..e8a98bb 100644 --- a/hook/hook_test.go +++ b/hook/hook_test.go @@ -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