Skip to content

Commit c5fe1fd

Browse files
authored
feat: field policies deep equal for nested data (#122)
1 parent 55f1de0 commit c5fe1fd

File tree

3 files changed

+70
-36
lines changed

3 files changed

+70
-36
lines changed

internals/proxy/middlewares/policy.go

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package middlewares
33
import (
44
"errors"
55
"net/http"
6+
"reflect"
67

78
"github.com/codeshelldev/secured-signal-api/internals/config/structure"
89
log "github.com/codeshelldev/secured-signal-api/utils/logger"
@@ -78,54 +79,75 @@ func getField(key string, body map[string]any, headers map[string][]string) (any
7879
return value, errors.New("field not found")
7980
}
8081

82+
func doPoliciesApply(body map[string]any, headers map[string][]string, policies map[string]structure.FieldPolicy) (bool, string) {
83+
for key, policy := range policies {
84+
value, err := getField(key, body, headers)
85+
86+
if err != nil {
87+
continue
88+
}
89+
90+
switch asserted := value.(type) {
91+
case string:
92+
policyValue, ok := policy.Value.(string)
93+
94+
if ok && asserted == policyValue {
95+
return true, key
96+
}
97+
case int:
98+
policyValue, ok := policy.Value.(int);
99+
100+
if ok && asserted == policyValue {
101+
return true, key
102+
}
103+
case bool:
104+
policyValue, ok := policy.Value.(bool)
105+
106+
if ok && asserted == policyValue {
107+
return true, key
108+
}
109+
default:
110+
if reflect.DeepEqual(value, policy.Value) {
111+
return true, key
112+
}
113+
}
114+
}
115+
116+
return false, ""
117+
}
118+
81119
func doBlock(body map[string]any, headers map[string][]string, policies map[string]structure.FieldPolicy) (bool, string) {
82-
if policies == nil {
83-
return false, ""
84-
} else if len(policies) <= 0 {
120+
if len(policies) == 0 {
121+
// default: allow all
85122
return false, ""
86123
}
87124

88125
allowed, blocked := getPolicies(policies)
89126

90127
var cause string
91128

92-
var isExplictlyAllowed, isExplicitlyBlocked bool
93-
94-
for field, policy := range allowed {
95-
value, err := getField(field, body, headers)
96-
97-
if value == policy.Value && err == nil {
98-
isExplictlyAllowed = true
99-
cause = field
100-
break
101-
}
129+
isExplicitlyAllowed, cause := doPoliciesApply(body, headers, allowed)
130+
isExplicitlyBlocked, cause := doPoliciesApply(body, headers, blocked)
131+
132+
// explicit allow > block
133+
if isExplicitlyAllowed {
134+
return false, cause
102135
}
103-
104-
for field, policy := range blocked {
105-
value, err := getField(field, body, headers)
106-
107-
if value == policy.Value && err == nil {
108-
isExplicitlyBlocked = true
109-
cause = field
110-
break
111-
}
112-
}
113-
114-
// Block all except explicitly Allowed
115-
if len(blocked) == 0 && len(allowed) != 0 {
116-
return !isExplictlyAllowed, cause
136+
137+
if isExplicitlyBlocked {
138+
return true, cause
117139
}
118140

119-
// Allow all except explicitly Blocked
120-
if len(allowed) == 0 && len(blocked) != 0 {
121-
return isExplicitlyBlocked, cause
141+
// only allow policies -> block anything not allowed
142+
if len(allowed) > 0 && len(blocked) == 0 {
143+
return true, cause
122144
}
123145

124-
// Excplicitly Blocked except excplictly Allowed
125-
if len(blocked) != 0 && len(allowed) != 0 {
126-
return isExplicitlyBlocked && !isExplictlyAllowed, cause
146+
// only block polcicies -> allow anything not blocked
147+
if len(blocked) > 0 && len(allowed) == 0 {
148+
return false, cause
127149
}
128150

129-
// Block all
130-
return true, ""
151+
// no match -> default: block all
152+
return true, cause
131153
}

utils/logger/logger.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ func Format(data ...any) string {
6060
res += value
6161
case int:
6262
res += strconv.Itoa(value)
63+
case bool:
64+
if value {
65+
res += "true"
66+
} else {
67+
res += "false"
68+
}
6369
default:
6470
lines := strings.Split(jsonutils.Pretty(value), "\n")
6571

utils/request/requestkeys/requestkeys.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ func PrefixHeaders(headers map[string][]string) map[string][]string {
4646
return res
4747
}
4848

49-
func GetFromBodyAndHeaders(field Field, body map[string]any, headers map[string][]string) any {
49+
func PrefixBodyAndHeaders(body map[string]any, headers map[string][]string) (map[string]any, map[string][]string) {
5050
body = PrefixBody(body)
5151
headers = PrefixHeaders(headers)
5252

53+
return body, headers
54+
}
55+
56+
func GetFromBodyAndHeaders(field Field, body map[string]any, headers map[string][]string) any {
57+
body, headers = PrefixBodyAndHeaders(body, headers)
58+
5359
switch(field.Prefix) {
5460
case BodyPrefix:
5561
return GetByField(field, body)

0 commit comments

Comments
 (0)