summaryrefslogtreecommitdiff
path: root/internal/configuration/decode_hooks.go
diff options
context:
space:
mode:
authorJames Elliott <james-d-elliott@users.noreply.github.com>2025-02-18 20:38:36 +1100
committerGitHub <noreply@github.com>2025-02-18 09:38:36 +0000
commita9d1986fa9dec8701ee73b05aa99781f4bbe5f18 (patch)
treebbcef1a55483271f43308179d4fd09ef8a894131 /internal/configuration/decode_hooks.go
parent7ac3c6a4f3945c3c4272bac717addd1ef598b2b9 (diff)
feat(configuration): reusable definitions (#8077)
This adds reusable definitions into the mix for the configuration. This replaces the existing networks section for the access_control section and is automatically remapped for users. Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
Diffstat (limited to 'internal/configuration/decode_hooks.go')
-rw-r--r--internal/configuration/decode_hooks.go73
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
+ }
+}