From 72c88ef538d4c74a0e29a11a0fd75984d9a053e7 Mon Sep 17 00:00:00 2001 From: kaanaktas Date: Sat, 20 Aug 2022 15:31:58 +0100 Subject: [PATCH] additional unit tests and fixes --- README.md | 2 +- common_test.go | 14 +++ datafilter/load.go | 6 +- datafilter_test.go | 29 +---- executor/executor.go | 2 +- main.go | 21 ++-- policy/load.go | 2 +- policy_load_test.go | 113 ++++++++++++++++++ .../common_policies.json | 0 testconfig/custom_datafilter_rule_set.json | 17 +++ .../custom_pan_process.json | 0 .../policy_rule_set.json | 0 testdata/datafilter_rule_set.json | 25 ---- 13 files changed, 161 insertions(+), 70 deletions(-) create mode 100644 common_test.go create mode 100644 policy_load_test.go rename {policy/testdata => testconfig}/common_policies.json (100%) create mode 100644 testconfig/custom_datafilter_rule_set.json rename testdata/pan_process_custom.json => testconfig/custom_pan_process.json (100%) rename {policy/testdata => testconfig}/policy_rule_set.json (100%) delete mode 100644 testdata/datafilter_rule_set.json diff --git a/README.md b/README.md index 6e08b47..0278390 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ In order for the newly created **custom_owasp_attack_sqli.json** file to be cons ` ## policy -We can create reusable policies in our common policy rule file (similar to **/testdata/common_policies.json**) and use them +We can create reusable policies in our common policy rule file (similar to **/testconfig/common_policies.json**) and use them to combine different policies in **policy_rule_set.json**. This file can be named based on requirement and should be defined in the **GO_SLM_COMMON_POLICIES_PATH** environment variable as in the example below. diff --git a/common_test.go b/common_test.go new file mode 100644 index 0000000..43b75c8 --- /dev/null +++ b/common_test.go @@ -0,0 +1,14 @@ +package main + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + _ = os.Setenv("GO_SLM_POLICY_RULE_SET_PATH", "/testconfig/policy_rule_set.json") + _ = os.Setenv("GO_SLM_COMMON_POLICIES_PATH", "/testconfig/common_policies.json") + _ = os.Setenv("GO_SLM_CURRENT_MODULE_NAME", "github.com/kaanaktas/dummy") + + os.Exit(m.Run()) +} diff --git a/datafilter/load.go b/datafilter/load.go index 828f287..74317ab 100644 --- a/datafilter/load.go +++ b/datafilter/load.go @@ -45,7 +45,7 @@ func Load(dataFilterRuleSetPath string) { } err = json.Unmarshal(content, &customRuleSet) if err != nil { - msg := fmt.Sprintf("Can't unmarshall the content of datafilter_rule_set.json. Error: %s", err) + msg := fmt.Sprintf("Can't unmarshall the content of %s. Error: %s", dataFilterRuleSetPath, err) panic(msg) } @@ -85,12 +85,12 @@ func Load(dataFilterRuleSetPath string) { if rule.CustomPath != "" { content, err = config.ReadFile(filepath.Join(config.RootDirectory, rule.CustomPath)) if err != nil { - msg := fmt.Sprintf("Error while reading %s. Error: %s", dataFilterRuleSetPath, err) + msg := fmt.Sprintf("Error while reading %s. Error: %s", rule.CustomPath, err) panic(msg) } err = json.Unmarshal(content, &customPatterns) if err != nil { - msg := fmt.Sprintf("Can't unmarshall the content of datafilter_rule_set.json. Error: %s", err) + msg := fmt.Sprintf("Can't unmarshall the content of %s. Error: %s", rule.CustomPath, err) panic(msg) } } diff --git a/datafilter_test.go b/datafilter_test.go index 90d9008..215f96a 100644 --- a/datafilter_test.go +++ b/datafilter_test.go @@ -1,22 +1,11 @@ package main import ( - "github.com/kaanaktas/go-slm/cache" "github.com/kaanaktas/go-slm/config" "github.com/kaanaktas/go-slm/executor" - "github.com/labstack/gommon/log" - "os" "testing" ) -func TestMain(m *testing.M) { - _ = os.Setenv("GO_SLM_POLICY_RULE_SET_PATH", "/policy/testdata/policy_rule_set.json") - _ = os.Setenv("GO_SLM_COMMON_RULES_PATH", "/policy/testdata/common_policies.json") - _ = os.Setenv("GO_SLM_CURRENT_MODULE_NAME", "github.com/kaanaktas/dummy") - - os.Exit(m.Run()) -} - func TestExecute(t *testing.T) { type args struct { data string @@ -45,7 +34,7 @@ func TestExecute(t *testing.T) { name: "test_pan_filter", panic: true, args: args{ - data: "44044333322221111swfkjbfjksjkf4444333322221111dedeefefefe", + data: "44044 3360110004012 8888 88881881990139424332 2221111", serviceName: "test", }}, { @@ -61,7 +50,6 @@ func TestExecute(t *testing.T) { defer func() { r := recover() if (r != nil) && tt.panic == false { - log.Error(r) t.Errorf("%s did panic", tt.name) } else if (r == nil) && tt.panic == true { t.Errorf("%s didn't panic", tt.name) @@ -71,18 +59,3 @@ func TestExecute(t *testing.T) { }) } } - -func TestCache(t *testing.T) { - _ = os.Setenv("GO_SLM_DATA_FILTER_RULE_SET_PATH", "/datafilter/testdata/datafilter_rule_set.json") - - cacheIn := cache.NewInMemory() - cacheIn.Flush() - - executor.Execute("test_sqli_filter", "test", config.Request) - if _, ok := cacheIn.Get("test_pan_process"); !ok { - t.Error("test_pan_process is not in the cache") - } - if _, ok := cacheIn.Get("pan_process"); !ok { - t.Error("pan_process is not in the cache") - } -} diff --git a/executor/executor.go b/executor/executor.go index a3898bf..d0f2a47 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -68,7 +68,7 @@ func Execute(data, serviceName, direction string) { case <-closeCh: } - log.Println("no_match with datafilter rules") + log.Println("no match with datafilter rules") } func processor(policies []policy.CommonPolicy, in chan<- datafilter.Validate, breaker <-chan string) { diff --git a/main.go b/main.go index 59ed4a5..a623abe 100644 --- a/main.go +++ b/main.go @@ -9,14 +9,6 @@ import ( "time" ) -func init() { - _ = os.Setenv("GO_SLM_COMMON_POLICIES_PATH", "/policy/testdata/common_policies.json") - _ = os.Setenv("GO_SLM_POLICY_RULE_SET_PATH", "/policy/testdata/policy_rule_set.json") - _ = os.Setenv("GO_SLM_DATA_FILTER_RULE_SET_PATH", "/testdata/datafilter_rule_set.json") - //pretending to be imported by another project - _ = os.Setenv("GO_SLM_CURRENT_MODULE_NAME", "github.com/kaanaktas/dummy") -} - func main() { defer config.Elapsed("Execution")() defer func() { @@ -24,19 +16,26 @@ func main() { log.Println("All Channels were closed successfully. Number of goroutine:", runtime.NumGoroutine()) }() + _ = os.Setenv("GO_SLM_COMMON_POLICIES_PATH", "/testconfig/common_policies.json") + _ = os.Setenv("GO_SLM_POLICY_RULE_SET_PATH", "/testconfig/policy_rule_set.json") + _ = os.Setenv("GO_SLM_DATA_FILTER_RULE_SET_PATH", "/testconfig/custom_datafilter_rule_set.json") + //pretending to be imported by another project + _ = os.Setenv("GO_SLM_CURRENT_MODULE_NAME", "github.com/kaanaktas/dummy") + serviceName := "test" - testData := [...]string{ + data := []string{ "clear data with no match", "admin' AND 1=1 --", - "http://testing.com/book.html?default=", + "https://testing.com/book.html?default=", "44044 3360110004012 8888 88881881990139424332 2221111"} - for _, data := range testData { + for _, data := range data { func() { defer func() { if r := recover(); r != nil { log.Println("Recovered in Execute", r) } + log.Println("--------") }() log.Println("Filtering data:", data) executor.Execute(data, serviceName, config.Request) diff --git a/policy/load.go b/policy/load.go index 95bc85b..aaaa030 100644 --- a/policy/load.go +++ b/policy/load.go @@ -9,7 +9,7 @@ import ( "path/filepath" ) -const Key = "access_rule" +const Key = "policy_rule" var cacheIn = cache.NewInMemory() diff --git a/policy_load_test.go b/policy_load_test.go new file mode 100644 index 0000000..0671fa9 --- /dev/null +++ b/policy_load_test.go @@ -0,0 +1,113 @@ +package main + +import ( + "github.com/kaanaktas/go-slm/cache" + "github.com/kaanaktas/go-slm/config" + "github.com/kaanaktas/go-slm/datafilter" + "github.com/kaanaktas/go-slm/executor" + "github.com/kaanaktas/go-slm/policy" + "os" + "testing" +) + +func TestDataFilterRuleLoad(t *testing.T) { + _ = os.Setenv("GO_SLM_DATA_FILTER_RULE_SET_PATH", "/testconfig/custom_datafilter_rule_set.json") + + cacheIn := cache.NewInMemory() + cacheIn.Flush() + + executor.Execute("test_data", "test", config.Request) + + type cachedDataFilterRule struct { + name string + size int + } + + tests := []struct { + name string + policy cachedDataFilterRule + }{ + { + name: "cached_pan_process", policy: cachedDataFilterRule{ + name: "pan_process", + size: 1, + }, + }, + { + name: "cached_custom_pan_process", policy: cachedDataFilterRule{ + name: "custom_pan_process", + size: 1, + }, + }, + { + name: "cached_sqli", policy: cachedDataFilterRule{ + name: "sqli", + size: 44, + }, + }, + { + name: "cached_xss", policy: cachedDataFilterRule{ + name: "xss", + size: 27, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if cachedData, ok := cacheIn.Get(test.policy.name); ok { + if len(cachedData.([]datafilter.Validate)) != test.policy.size { + t.Errorf("cached data size doesn't match up. Expected: %d, got:%d", test.policy.size, + len(cachedData.([]datafilter.Validate))) + } + } else { + t.Errorf("%s is not in the cache", test.policy.name) + } + }) + } +} + +func TestPolicyLoad(t *testing.T) { + cacheIn := cache.NewInMemory() + cacheIn.Flush() + + executor.Execute("test_data", "test", config.Request) + + type cachedPolicyRule struct { + name string + size int + policies []string + } + + tests := []struct { + name string + policy cachedPolicyRule + }{ + { + name: "cached_policy_rule", policy: cachedPolicyRule{ + name: "policy_rule", + size: 4, + policies: []string{"test_request", "test_response", "test2_request", "test2_response"}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if cachedData, ok := cacheIn.Get(test.policy.name); ok { + if len(cachedData.(policy.CommonPolicyMap)) != test.policy.size { + t.Errorf("cached data size doesn't match up. Expected: %d, got:%d", test.policy.size, + len(cachedData.(policy.CommonPolicyMap))) + } + for _, v := range test.policy.policies { + cachedPolicies := cachedData.(policy.CommonPolicyMap) + if _, exists := cachedPolicies[v]; !exists { + t.Errorf("%s is not in the policy rule set", v) + } + } + } else { + t.Errorf("%s is not in the policies", test.policy.name) + } + }) + } +} diff --git a/policy/testdata/common_policies.json b/testconfig/common_policies.json similarity index 100% rename from policy/testdata/common_policies.json rename to testconfig/common_policies.json diff --git a/testconfig/custom_datafilter_rule_set.json b/testconfig/custom_datafilter_rule_set.json new file mode 100644 index 0000000..07f47d4 --- /dev/null +++ b/testconfig/custom_datafilter_rule_set.json @@ -0,0 +1,17 @@ +[ + { + "type": "pan", + "rules": [ + { + "name": "pan_process", + "path": "rules/pan_process.json", + "custom_path": "/testconfig/custom_pan_process.json" + }, + { + "name": "custom_pan_process", + "path": "rules/pan_process.json", + "custom_path": "" + } + ] + } +] diff --git a/testdata/pan_process_custom.json b/testconfig/custom_pan_process.json similarity index 100% rename from testdata/pan_process_custom.json rename to testconfig/custom_pan_process.json diff --git a/policy/testdata/policy_rule_set.json b/testconfig/policy_rule_set.json similarity index 100% rename from policy/testdata/policy_rule_set.json rename to testconfig/policy_rule_set.json diff --git a/testdata/datafilter_rule_set.json b/testdata/datafilter_rule_set.json deleted file mode 100644 index fd04cf4..0000000 --- a/testdata/datafilter_rule_set.json +++ /dev/null @@ -1,25 +0,0 @@ -[ - { - "type": "pan", - "rules": [ - { - "name": "pan_process", - "path": "rules/pan_process.json", - "custom_path": "testdata/pan_process_custom.json" - } - ] - }, - { - "type": "owasp", - "rules": [ - { - "name": "sqli", - "path": "rules/owasp_attack_sqli.json" - }, - { - "name": "xss", - "path": "rules/owasp_attack_xss.json" - } - ] - } -]