From 4867269ae975bb675adbfa729f2b6dd6515c56c1 Mon Sep 17 00:00:00 2001 From: manuwelakanade <42827843+manuwelakanade@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:34:29 +0530 Subject: [PATCH] MFW 4883 fixing db settings (#391) * util: move DecodeAttribute into it's own function, add it to util_test as well, testing the error that broke main branch devices * database settings: move settings over to golang-shared, add basic unmarshal testers * MFW-4883 Fixing unit tests for decode string util function * MFW-4883 Adding interface settings * MFW-4883 Added an extra password attribute * MFW-4883 Fixing database password attr name * MFW-4883 Fixing interfaces settings * Added encrypted password attributed for pppoe * Added attributes for interfaces * MFW-4883 Removing interface structs --------- Co-authored-by: John Sommerville version: bug --- .../appstates/appstate_service_state.json | 2 +- .../settings/database_settings/database.go | 17 +++ .../database_settings_test.go | 123 ++++++++++++++++++ .../settings/database_settings/databases.go | 5 + util/util.go | 20 +++ util/util_test.go | 42 ++++++ 6 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 services/settings/database_settings/database.go create mode 100644 services/settings/database_settings/database_settings_test.go create mode 100644 services/settings/database_settings/databases.go diff --git a/services/licensemanager/testdata/appstates/appstate_service_state.json b/services/licensemanager/testdata/appstates/appstate_service_state.json index 1460f8c4..258a75ee 100644 --- a/services/licensemanager/testdata/appstates/appstate_service_state.json +++ b/services/licensemanager/testdata/appstates/appstate_service_state.json @@ -1 +1 @@ -[{"name":"untangle-node-captiveportal","allowedState":0},{"name":"untangle-node-threat-prevention","allowedState":1},{"name":"untangle-node-sitefilter","allowedState":0},{"name":"untangle-node-geoip","allowedState":0},{"name":"untangle-node-discovery","allowedState":0},{"name":"untangle-node-classd","allowedState":1},{"name":"untangle-node-dynamic-lists","allowedState":0}] \ No newline at end of file +[{"name":"untangle-node-discovery","allowedState":0},{"name":"untangle-node-classd","allowedState":1},{"name":"untangle-node-dynamic-lists","allowedState":0},{"name":"untangle-node-captiveportal","allowedState":0},{"name":"untangle-node-threat-prevention","allowedState":1},{"name":"untangle-node-sitefilter","allowedState":0},{"name":"untangle-node-geoip","allowedState":0}] \ No newline at end of file diff --git a/services/settings/database_settings/database.go b/services/settings/database_settings/database.go new file mode 100644 index 00000000..0508a705 --- /dev/null +++ b/services/settings/database_settings/database.go @@ -0,0 +1,17 @@ +package database_settings + +type Database struct { + Enabled bool `json:"enabled"` + ID string `json:"id"` + Database string `json:"db_name"` + UserName string `json:"db_username"` + Password string `json:"db_password"` + PasswordEncrypted string `json:"db_password_encrypted"` + Server string `json:"db_server"` + Port int `json:"db_port"` + Description string `json:"description"` + Name string `json:"name"` + Type string `json:"type"` + ConnectionString string `json:"db_connection_string"` + Default bool `json:"default"` +} diff --git a/services/settings/database_settings/database_settings_test.go b/services/settings/database_settings/database_settings_test.go new file mode 100644 index 00000000..a6871334 --- /dev/null +++ b/services/settings/database_settings/database_settings_test.go @@ -0,0 +1,123 @@ +package database_settings + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +// unnmarshalTest stolen from policy tests - we can probably generalize this to be reused across areas better +type unmarshalTest struct { + name string + json string + expectedErr bool + expected Databases +} + +// runUnmarshalTest runs the unmarshal test. +func runUnmarshalTest(t *testing.T, tests []unmarshalTest) { + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var actual Databases + if !tt.expectedErr { + assert.NoError(t, json.Unmarshal([]byte(tt.json), &actual)) + assert.EqualValues(t, actual, tt.expected) + } else { + assert.Error(t, json.Unmarshal([]byte(tt.json), &actual)) + } + }) + } +} + +// TestDatabaseUnmarshal tests unmarshalling the database settings +func TestDatabaseUnmarshal(t *testing.T) { + tests := []unmarshalTest{ + { + name: "Generic database settings unmarshal test", + json: `{"databases": [{"enabled": true, + "db_name": "testingdb", + "db_username": "test_user", + "db_password": "test_pw", + "db_server": "test_server", + "db_port": 5, + "description": "Some desc", + "name": "New DB Source", + "type": "DB Type 5", + "default": false, + "db_connection_string": "asdfasdfasdf" + }]}`, + expectedErr: false, + expected: Databases{ + []Database{ + { + Enabled: true, + Database: "testingdb", + UserName: "test_user", + Password: "test_pw", + Server: "test_server", + Port: 5, + Description: "Some desc", + Name: "New DB Source", + Type: "DB Type 5", + Default: false, + ConnectionString: "asdfasdfasdf", + }, + }, + }, + }, + { + name: "Default sqlite DB test", + json: `{"databases": [ + { + "db_connection_string": "sqlite:///tmp/reports.db", + "db_name": "reports.db", + "db_username": "", + "db_password": "", + "db_server": "", + "db_port": 0, + "description": "Local reports database", + "enabled": true, + "id": "66a6bc90-2f5e-4dc3-8180-a7cf4133daf2", + "name": "Local DB", + "type": "sqlite", + "default": true + }]}`, + expectedErr: false, + expected: Databases{ + []Database{ + { + Enabled: true, + ConnectionString: "sqlite:///tmp/reports.db", + Database: "reports.db", + UserName: "", + Password: "", + Server: "", + Port: 0, + Description: "Local reports database", + Name: "Local DB", + Type: "sqlite", + Default: true, + ID: "66a6bc90-2f5e-4dc3-8180-a7cf4133daf2", + }, + }, + }}, + { + name: "bad rule object type", + json: `{"name": "Geo Rule Tester", + "id": "c2428365-65be-4901-bfc0-bde2b310fedf", + "type": "asdfasdf", + "description": "Whatever", + "conditions": ["1458dc12-a9c2-4d0c-8203-1340c61c2c3b"], + "action": { + "type": "SET_CONFIGURATION", + "configuration_id": "1202b42e-2f21-49e9-b42c-5614e04d0031", + "key": "GeoipRuleObject" + } + }`, + expectedErr: false, + expected: Databases{}, + }, + } + runUnmarshalTest(t, tests) +} diff --git a/services/settings/database_settings/databases.go b/services/settings/database_settings/databases.go new file mode 100644 index 00000000..eb4ed036 --- /dev/null +++ b/services/settings/database_settings/databases.go @@ -0,0 +1,5 @@ +package database_settings + +type Databases struct { + Databases []Database `json:"databases"` +} diff --git a/util/util.go b/util/util.go index 35f65e2e..ccce6fef 100644 --- a/util/util.go +++ b/util/util.go @@ -4,6 +4,8 @@ import ( "archive/tar" "bytes" "compress/gzip" + "encoding/base64" + "fmt" "io" "math/rand" "strings" @@ -102,3 +104,21 @@ func ExtractFilesFromTar(b []byte, isGzip bool, fileName ...string) (map[string] return foundFiles, nil } + +// DecodeAttribute is used to decode strings into base64 encoded strings +func DecodeAttribute(value string) (string, error) { + const num = 2 + // check for empty interface value + if value == "" { + return "", nil + } + + stringValue := fmt.Sprintf("%v", value) + rightStart := stringValue[len(stringValue)-num:] + rightEnd := stringValue[0 : len(stringValue)-num] + decodedBytes, err := base64.StdEncoding.DecodeString(rightStart + rightEnd) + if err != nil { + return "", err + } + return string(decodedBytes), nil +} diff --git a/util/util_test.go b/util/util_test.go index 3e8899b6..283324df 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -161,3 +161,45 @@ func TestStringArrayToDB(t *testing.T) { }) } } + +// Test DecodeAttribute functions +func TestDecodeAttribute(t *testing.T) { + tests := []struct { + name string + input string + expected string + errorExpected bool + }{ + { + name: "Null string input", + input: "", + expected: "", + errorExpected: false, + }, + { + name: "String value test", + input: "Testingval", + expected: "", + errorExpected: true, + }, + { + name: "b64 encoded string value test", + input: "VzdGluZ3ZhbA==VG", + expected: "Testingval", + errorExpected: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if !test.errorExpected { + actual, err := DecodeAttribute(test.input) + assert.Equal(t, test.expected, actual) + assert.NoError(t, err) + } else { + _, err := DecodeAttribute(test.input) + assert.Error(t, err) + } + }) + } +}