Skip to content

Commit 03bbd29

Browse files
authored
fix: normalize field policy (#105)
1 parent 2a106fa commit 03bbd29

File tree

8 files changed

+393
-145
lines changed

8 files changed

+393
-145
lines changed

data/defaults.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ settings:
3232

3333
access:
3434
endpoints:
35-
- !/v1/about
36-
- !/v1/configuration
37-
- !/v1/devices
38-
- !/v1/register
39-
- !/v1/unregister
40-
- !/v1/qrcodelink
41-
- !/v1/accounts
42-
- !/v1/contacts
35+
- "!/v1/about"
36+
- "!/v1/configuration"
37+
- "!/v1/devices"
38+
- "!/v1/register"
39+
- "!/v1/unregister"
40+
- "!/v1/qrcodelink"
41+
- "!/v1/accounts"
42+
- "!/v1/contacts"

internals/config/loader.go

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ var ENV *structure.ENV = &structure.ENV{
2525
INSECURE: false,
2626
}
2727

28-
var defaultsConf = configutils.New()
29-
var userConf = configutils.New()
30-
var tokenConf = configutils.New()
28+
var defaultsConf *configutils.Config
29+
var userConf *configutils.Config
30+
var tokenConf *configutils.Config
3131

32-
var config = configutils.New()
32+
var mainConf *configutils.Config
3333

3434
func Load() {
35+
Clear()
36+
3537
InitReload()
3638

3739
LoadDefaults()
@@ -42,39 +44,90 @@ func Load() {
4244

4345
userConf.LoadEnv()
4446

45-
config.MergeLayers(defaultsConf.Layer, userConf.Layer)
47+
NormalizeConfig(defaultsConf)
48+
NormalizeConfig(userConf)
49+
50+
NormalizeTokens()
51+
52+
mainConf.MergeLayers(defaultsConf.Layer, userConf.Layer)
4653

47-
config.NormalizeKeys()
48-
config.TemplateConfig()
54+
mainConf.TemplateConfig()
4955

5056
InitTokens()
5157

5258
InitEnv()
5359

5460
log.Info("Finished Loading Configuration")
5561

56-
log.Dev("Loaded Config:\n" + jsonutils.ToJson(config.Layer.All()))
62+
log.Dev("Loaded Config:\n" + jsonutils.ToJson(mainConf.Layer.All()))
5763
log.Dev("Loaded Token Configs:\n" + jsonutils.ToJson(tokenConf.Layer.All()))
5864
}
5965

66+
func Clear() {
67+
defaultsConf = configutils.New()
68+
userConf = configutils.New()
69+
tokenConf = configutils.New()
70+
mainConf = configutils.New()
71+
}
72+
73+
func LowercaseKeys(config *configutils.Config) {
74+
data := map[string]any{}
75+
76+
for _, key := range config.Layer.Keys() {
77+
lower := strings.ToLower(key)
78+
79+
data[lower] = config.Layer.Get(key)
80+
}
81+
82+
config.Layer.Delete("")
83+
config.Load(data, "")
84+
}
85+
86+
func NormalizeConfig(config *configutils.Config) {
87+
Normalize(config, "settings", &structure.SETTINGS{})
88+
}
89+
90+
func Normalize(config *configutils.Config, path string, structure any) {
91+
data := config.Layer.Get(path)
92+
old, ok := data.(map[string]any)
93+
94+
if !ok {
95+
log.Warn("Could not load `"+path+"`")
96+
return
97+
}
98+
99+
// Create temporary config
100+
tmpConf := configutils.New()
101+
tmpConf.Load(old, "")
102+
103+
// Apply transforms to the new config
104+
tmpConf.ApplyTransformFuncs(structure, "", transformFuncs)
105+
106+
// Lowercase actual config
107+
LowercaseKeys(config)
108+
109+
// Load temporary config back into paths
110+
config.Layer.Delete(path)
111+
112+
config.Load(tmpConf.Layer.All(), path)
113+
}
114+
60115
func InitReload() {
61116
defaultsConf.OnLoad(Load)
62117
userConf.OnLoad(Load)
63118
tokenConf.OnLoad(Load)
64119
}
65120

66121
func InitEnv() {
67-
ENV.PORT = strconv.Itoa(config.Layer.Int("service.port"))
122+
ENV.PORT = strconv.Itoa(mainConf.Layer.Int("service.port"))
68123

69-
ENV.LOG_LEVEL = strings.ToLower(config.Layer.String("loglevel"))
124+
ENV.LOG_LEVEL = strings.ToLower(mainConf.Layer.String("loglevel"))
70125

71-
ENV.API_URL = config.Layer.String("api.url")
126+
ENV.API_URL = mainConf.Layer.String("api.url")
72127

73128
var settings structure.SETTINGS
74129

75-
config.TransformChildren("settings.message.variables", transformVariables)
76-
77-
config.Layer.Unmarshal("settings", &settings)
130+
mainConf.Layer.Unmarshal("settings", &settings)
78131

79132
ENV.SETTINGS["*"] = &settings
80133
}
@@ -101,8 +154,4 @@ func LoadConfig() {
101154

102155
log.Error("Could not Load Config ", ENV.CONFIG_PATH, ": ", err.Error())
103156
}
104-
}
105-
106-
func transformVariables(key string, value any) (string, any) {
107-
return strings.ToUpper(key), value
108-
}
157+
}

internals/config/parser.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package config
2+
3+
import (
4+
"strings"
5+
)
6+
7+
var transformFuncs = map[string]func(string, any) (string, any) {
8+
"default": defaultTransform,
9+
"lower": lowercaseTransform,
10+
"upper": uppercaseTransform,
11+
}
12+
13+
func defaultTransform(key string, value any) (string, any) {
14+
return key, value
15+
}
16+
17+
func lowercaseTransform(key string, value any) (string, any) {
18+
return strings.ToLower(key), value
19+
}
20+
21+
func uppercaseTransform(key string, value any) (string, any) {
22+
return strings.ToUpper(key), value
23+
}

internals/config/structure/structure.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,32 @@ type ENV struct {
99
PORT string
1010
API_URL string
1111
API_TOKENS []string
12-
SETTINGS map[string]*SETTINGS
12+
SETTINGS map[string]*SETTINGS `koanf:"settings"`
1313
INSECURE bool
1414
}
1515

1616
type SETTINGS struct {
17-
ACCESS ACCESS_SETTINGS `koanf:"access"`
18-
MESSAGE MESSAGE_SETTINGS `koanf:"message"`
17+
ACCESS ACCESS_SETTINGS `koanf:"access" transform:"lower"`
18+
MESSAGE MESSAGE_SETTINGS `koanf:"message" transform:"lower"`
1919
}
2020

2121
type MESSAGE_SETTINGS struct {
22-
VARIABLES map[string]any `koanf:"variables"`
23-
FIELD_MAPPINGS map[string][]FieldMapping `koanf:"fieldmappings"`
24-
TEMPLATE string `koanf:"template"`
22+
VARIABLES map[string]any `koanf:"variables" childtransform:"upper"`
23+
FIELD_MAPPINGS map[string][]FieldMapping `koanf:"fieldmappings" childtransform:"default"`
24+
TEMPLATE string `koanf:"template" transform:"lower"`
2525
}
2626

2727
type FieldMapping struct {
28-
Field string `koanf:"field"`
29-
Score int `koanf:"score"`
28+
Field string `koanf:"field" transform:"lower"`
29+
Score int `koanf:"score" transform:"lower"`
3030
}
3131

3232
type ACCESS_SETTINGS struct {
33-
ENDPOINTS []string `koanf:"endpoints"`
34-
FIELD_POLOCIES map[string]FieldPolicy `koanf:"fieldpolicies"`
33+
ENDPOINTS []string `koanf:"endpoints" transform:"lower"`
34+
FIELD_POLICIES map[string]FieldPolicy `koanf:"fieldpolicies" transform:"lower" childtransform:"default"`
3535
}
3636

3737
type FieldPolicy struct {
38-
Value any `koanf:"value"`
39-
Action string `koanf:"action"`
38+
Value any `koanf:"value" transform:"lower"`
39+
Action string `koanf:"action" transform:"lower"`
4040
}

internals/config/tokens.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import (
44
"strconv"
55

66
"github.com/codeshelldev/secured-signal-api/internals/config/structure"
7+
"github.com/codeshelldev/secured-signal-api/utils/configutils"
78
log "github.com/codeshelldev/secured-signal-api/utils/logger"
89
"github.com/knadh/koanf/parsers/yaml"
910
)
1011

11-
type TOKEN_CONFIG_ struct {
12+
type TOKEN_CONFIG struct {
1213
TOKENS []string `koanf:"tokens"`
1314
OVERRIDES structure.SETTINGS `koanf:"overrides"`
1415
}
@@ -22,17 +23,29 @@ func LoadTokens() {
2223
log.Error("Could not Load Configs in ", ENV.TOKENS_DIR, ": ", err.Error())
2324
}
2425

25-
tokenConf.NormalizeKeys()
26-
2726
tokenConf.TemplateConfig()
2827
}
2928

30-
func InitTokens() {
31-
apiTokens := config.Layer.Strings("api.tokens")
29+
func NormalizeTokens() {
30+
configArray := []map[string]any{}
31+
32+
for _, config := range tokenConf.Layer.Slices("tokenconfigs") {
33+
tmpConf := configutils.New()
34+
tmpConf.Load(config.All(), "")
35+
36+
Normalize(tmpConf, "overrides", &structure.SETTINGS{})
37+
38+
configArray = append(configArray, tmpConf.Layer.All())
39+
}
40+
41+
// Merge token configs together into new temporary config
42+
tokenConf.Layer.Set("tokenconfigs", configArray)
43+
}
3244

33-
var tokenConfigs []TOKEN_CONFIG_
45+
func InitTokens() {
46+
apiTokens := mainConf.Layer.Strings("api.tokens")
3447

35-
tokenConf.TransformChildrenUnderArray("tokenconfigs", "overrides.message.variables", transformVariables)
48+
var tokenConfigs []TOKEN_CONFIG
3649

3750
tokenConf.Layer.Unmarshal("tokenconfigs", &tokenConfigs)
3851

@@ -53,7 +66,7 @@ func InitTokens() {
5366

5467
// Set Blocked Endpoints on Config to User Layer Value
5568
// => effectively ignoring Default Layer
56-
config.Layer.Set("settings.access.endpoints", userConf.Layer.Strings("settings.access.endpoints"))
69+
mainConf.Layer.Set("settings.access.endpoints", userConf.Layer.Strings("settings.access.endpoints"))
5770
}
5871

5972
if len(apiTokens) > 0 {
@@ -63,7 +76,7 @@ func InitTokens() {
6376
}
6477
}
6578

66-
func parseTokenConfigs(configs []TOKEN_CONFIG_) map[string]structure.SETTINGS {
79+
func parseTokenConfigs(configs []TOKEN_CONFIG) map[string]structure.SETTINGS {
6780
settings := map[string]structure.SETTINGS{}
6881

6982
for _, config := range configs {

internals/proxy/middlewares/policy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ func policyHandler(next http.Handler) http.Handler {
1919
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
2020
settings := getSettingsByReq(req)
2121

22-
policies := settings.ACCESS.FIELD_POLOCIES
22+
policies := settings.ACCESS.FIELD_POLICIES
2323

2424
if policies == nil {
25-
policies = getSettings("*").ACCESS.FIELD_POLOCIES
25+
policies = getSettings("*").ACCESS.FIELD_POLICIES
2626
}
2727

2828
body, err := request.GetReqBody(req)

0 commit comments

Comments
 (0)