From 878f5700f05e1be9ac08f3c2dd84cadd601296c9 Mon Sep 17 00:00:00 2001 From: dharmendra Date: Fri, 8 Jul 2016 19:04:08 +0900 Subject: [PATCH] Fix mask_dict_password for non string/dict type key in dict mask_dict_password method removes the keys from passed dict if those are not - indicative of password - Dict - String type So keys with value None or other type than string/dict are being removed. This method should just change the password with secret and return other Key as it is without any removal or alter. Change-Id: I21294ce6fd25a3e6438de41949d4427b17945bb2 Closes-Bug: #1600168 --- oslo_utils/strutils.py | 3 ++- oslo_utils/tests/test_strutils.py | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/oslo_utils/strutils.py b/oslo_utils/strutils.py index ae4d00db..10ebac0c 100644 --- a/oslo_utils/strutils.py +++ b/oslo_utils/strutils.py @@ -17,6 +17,7 @@ System-level utilities and helper functions. """ +import copy import math import re import unicodedata @@ -353,7 +354,7 @@ def mask_dict_password(dictionary, secret="***"): # nosec raise TypeError("Expected a dictionary, got %s instead." % type(dictionary)) - out = {} + out = copy.deepcopy(dictionary) for k, v in dictionary.items(): if isinstance(v, dict): diff --git a/oslo_utils/tests/test_strutils.py b/oslo_utils/tests/test_strutils.py index 0560d080..138ff648 100644 --- a/oslo_utils/tests/test_strutils.py +++ b/oslo_utils/tests/test_strutils.py @@ -15,6 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. +import copy import math import mock @@ -640,6 +641,29 @@ class MaskDictionaryPasswordTestCase(test_base.BaseTestCase): self.assertEqual(expected, strutils.mask_dict_password(payload)) + def test_other_non_str_values(self): + payload = {'password': 'DK0PK1AK3', 'bool': True, + 'dict': {'cat': 'meow', 'password': "*aa38skdjf"}, + 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, + 'str': 'foo'} + expected = {'password': '***', 'bool': True, + 'dict': {'cat': 'meow', 'password': '***'}, + 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, + 'str': 'foo'} + self.assertEqual(expected, + strutils.mask_dict_password(payload)) + + def test_argument_untouched(self): + """Make sure that the argument passed in is not modified""" + payload = {'password': 'DK0PK1AK3', 'bool': True, + 'dict': {'cat': 'meow', 'password': "*aa38skdjf"}, + 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, + 'str': 'foo'} + pristine = copy.deepcopy(payload) + # Send the payload into the function, to see if it gets modified + strutils.mask_dict_password(payload) + self.assertEqual(pristine, payload) + class IsIntLikeTestCase(test_base.BaseTestCase): def test_is_int_like_true(self):