diff options
Diffstat (limited to 'internal/configuration/decode_hooks.go')
| -rw-r--r-- | internal/configuration/decode_hooks.go | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/internal/configuration/decode_hooks.go b/internal/configuration/decode_hooks.go index 02610567e..c92834d2f 100644 --- a/internal/configuration/decode_hooks.go +++ b/internal/configuration/decode_hooks.go @@ -5,7 +5,9 @@ import ( "crypto/ed25519" "crypto/rsa" "crypto/x509" + "encoding/base64" "fmt" + "net" "net/mail" "net/url" "reflect" @@ -602,6 +604,14 @@ func StringToCryptographicKeyHookFunc() mapstructure.DecodeHookFuncType { dataStr := data.(string) if value, err = utils.ParseX509FromPEM([]byte(dataStr)); err != nil { + if !strings.Contains(dataStr, "\n") && !strings.HasPrefix(dataStr, "-----") { + var key []byte + + if key, err = base64.URLEncoding.DecodeString(dataStr); err == nil { + return key, nil + } + } + return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "", expectedType, err) } @@ -750,3 +760,66 @@ func StringToPasswordDigestHookFunc() mapstructure.DecodeHookFuncType { return *result, nil } } + +//nolint:gocyclo +func StringToIPNetworksHookFunc(definitions map[string][]*net.IPNet) mapstructure.DecodeHookFuncType { + return func(f reflect.Type, t reflect.Type, data any) (value any, err error) { + if f.Kind() != reflect.String && (f.Kind() != reflect.Slice || (f.Elem().Kind() != reflect.Interface && f.Elem().Kind() != reflect.String)) { + return data, nil + } + + expectedType := reflect.TypeOf(net.IPNet{}) + + isSlice := t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Ptr && t.Elem().Elem() == expectedType + isKind := t.Kind() == reflect.Ptr && t.Elem() == expectedType + + if !isSlice && !isKind { + return data, nil + } + + var values []string + + switch d := data.(type) { + case string: + values = []string{d} + case []string: + values = d + case []any: + values = make([]string, 0, len(d)) + + for i := range d { + switch v := d[i].(type) { + case string: + values = append(values, v) + default: + values = append(values, fmt.Sprint(v)) + } + } + } + + var ( + ok bool + definition []*net.IPNet + networks []*net.IPNet + network *net.IPNet + ) + + for _, str := range values { + if definitions != nil { + if definition, ok = definitions[str]; ok { + networks = append(networks, definition...) + + continue + } + } + + if network, err = utils.ParseHostCIDR(str); err != nil { + return nil, fmt.Errorf("failed to parse network %q: %w", str, err) + } + + networks = append(networks, network) + } + + return networks, nil + } +} |
