Commit f5e4eede authored by Slawek Figiel's avatar Slawek Figiel
Browse files

[#682] Move hide sensitive data function

parent 28d9d9fe
......@@ -6,7 +6,6 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
storkutil "isc.org/stork/util"
"muzzammil.xyz/jsonc"
)
......@@ -463,7 +462,36 @@ func (c *Map) GetGlobalReservationModes() *ReservationModes {
// Hide any sensitive data in the config.
func (c *Map) HideSensitiveData() {
storkutil.HideSensitiveData((*map[string]interface{})(c))
hideSensitiveData((*map[string]interface{})(c))
}
// Hide any sensitive data in the object. Data is sensitive if its key is equal to "password", "token" or "secret".
func hideSensitiveData(obj *map[string]interface{}) {
for entryKey, entryValue := range *obj {
// Check if the value holds sensitive data.
entryKeyNormalized := strings.ToLower(entryKey)
if entryKeyNormalized == "password" || entryKeyNormalized == "secret" || entryKeyNormalized == "token" {
(*obj)[entryKey] = nil
continue
}
// Check if it is an array.
array, ok := entryValue.([]interface{})
if ok {
for _, arrayItemValue := range array {
// Check if it is a subobject (or array).
subobject, ok := arrayItemValue.(map[string]interface{})
if ok {
hideSensitiveData(&subobject)
}
}
continue
}
// Check if it is a subobject (but not array).
subobject, ok := entryValue.(map[string]interface{})
if ok {
hideSensitiveData(&subobject)
}
}
}
// Convenience function used to check if a given host reservation
......
......@@ -889,3 +889,51 @@ func TestIsInAnyReservationModes(t *testing.T) {
return modes.IsOutOfPool()
}, modes[0], modes[0]))
}
// Test that the sensitive data are hidden.
func TestHideSensitiveData(t *testing.T) {
// Arrange
input := map[string]interface{}{
"foo": "bar",
"password": "xxx",
"token": "",
"secret": "aaa",
"first": map[string]interface{}{
"foo": "baz",
"Password": 42,
"Token": nil,
"Secret": "bbb",
"second": map[string]interface{}{
"foo": "biz",
"passworD": true,
"tokeN": "yyy",
"secreT": "ccc",
},
},
}
keaMap := New(&input)
// Act
keaMap.HideSensitiveData()
data := *keaMap
// Assert
// Top level
require.EqualValues(t, "bar", data["foo"])
require.EqualValues(t, nil, data["password"])
require.EqualValues(t, nil, data["token"])
require.EqualValues(t, nil, data["secret"])
// First level of the nesting
first := data["first"].(map[string]interface{})
require.EqualValues(t, "baz", first["foo"])
require.EqualValues(t, nil, first["Password"])
require.EqualValues(t, nil, first["Token"])
require.EqualValues(t, nil, first["Secret"])
// Second level of the nesting
second := first["second"].(map[string]interface{})
require.EqualValues(t, "biz", second["foo"])
require.EqualValues(t, nil, second["passworD"])
require.EqualValues(t, nil, second["tokeN"])
require.EqualValues(t, nil, second["secreT"])
}
......@@ -261,35 +261,6 @@ func readFileWithIncludes(path string, parentPaths map[string]bool) (string, err
return text, nil
}
// Hide any sensitive data in the object. Data is sensitive if its key is equal to "password", "token" or "secret".
func HideSensitiveData(obj *map[string]interface{}) {
for entryKey, entryValue := range *obj {
// Check if the value holds sensitive data.
entryKeyNormalized := strings.ToLower(entryKey)
if entryKeyNormalized == "password" || entryKeyNormalized == "secret" || entryKeyNormalized == "token" {
(*obj)[entryKey] = nil
continue
}
// Check if it is an array.
array, ok := entryValue.([]interface{})
if ok {
for _, arrayItemValue := range array {
// Check if it is a subobject (or array).
subobject, ok := arrayItemValue.(map[string]interface{})
if ok {
HideSensitiveData(&subobject)
}
}
continue
}
// Check if it is a subobject (but not array).
subobject, ok := entryValue.(map[string]interface{})
if ok {
HideSensitiveData(&subobject)
}
}
}
// Check if the filename has a conventional timestamp prefix.
// Returns a parsed timestamp, rest of filename and error (if failed).
func ParseTimestampPrefix(filename string) (time.Time, string, error) {
......
......@@ -227,51 +227,6 @@ func TestReadConfigurationWithNonExistingIncludes(t *testing.T) {
require.Error(t, err)
}
// Test that the sensitive data are hidden.
func TestHideSensitiveData(t *testing.T) {
// Arrange
data := map[string]interface{}{
"foo": "bar",
"password": "xxx",
"token": "",
"secret": "aaa",
"first": map[string]interface{}{
"foo": "baz",
"Password": 42,
"Token": nil,
"Secret": "bbb",
"second": map[string]interface{}{
"foo": "biz",
"passworD": true,
"tokeN": "yyy",
"secreT": "ccc",
},
},
}
// Act
HideSensitiveData(&data)
// Assert
// Top level
require.EqualValues(t, "bar", data["foo"])
require.EqualValues(t, nil, data["password"])
require.EqualValues(t, nil, data["token"])
require.EqualValues(t, nil, data["secret"])
// First level of the nesting
first := data["first"].(map[string]interface{})
require.EqualValues(t, "baz", first["foo"])
require.EqualValues(t, nil, first["Password"])
require.EqualValues(t, nil, first["Token"])
require.EqualValues(t, nil, first["Secret"])
// Second level of the nesting
second := first["second"].(map[string]interface{})
require.EqualValues(t, "biz", second["foo"])
require.EqualValues(t, nil, second["passworD"])
require.EqualValues(t, nil, second["tokeN"])
require.EqualValues(t, nil, second["secreT"])
}
// Function for a valid prefix should return no error.
func TestParseTimestampPrefixNoErrorForValid(t *testing.T) {
// Arrange
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment