Merge "Support non-dict mappings in mask_dict_password"
This commit is contained in:
commit
380bf5a47e
|
@ -17,6 +17,7 @@
|
||||||
System-level utilities and helper functions.
|
System-level utilities and helper functions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import collections
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
@ -390,12 +391,12 @@ def mask_dict_password(dictionary, secret="***"): # nosec
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not isinstance(dictionary, dict):
|
if not isinstance(dictionary, collections.Mapping):
|
||||||
raise TypeError("Expected a dictionary, got %s instead."
|
raise TypeError("Expected a Mapping, got %s instead."
|
||||||
% type(dictionary))
|
% type(dictionary))
|
||||||
out = {}
|
out = {}
|
||||||
for k, v in dictionary.items():
|
for k, v in dictionary.items():
|
||||||
if isinstance(v, dict):
|
if isinstance(v, collections.Mapping):
|
||||||
out[k] = mask_dict_password(v, secret=secret)
|
out[k] = mask_dict_password(v, secret=secret)
|
||||||
continue
|
continue
|
||||||
# NOTE(jlvillal): Check to see if anything in the dictionary 'key'
|
# NOTE(jlvillal): Check to see if anything in the dictionary 'key'
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import collections
|
||||||
import copy
|
import copy
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
@ -613,6 +614,31 @@ class MaskPasswordTestCase(test_base.BaseTestCase):
|
||||||
self.assertEqual(expected, strutils.mask_password(payload))
|
self.assertEqual(expected, strutils.mask_password(payload))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMapping(collections.Mapping):
|
||||||
|
"""Test class for non-dict mappings"""
|
||||||
|
def __init__(self):
|
||||||
|
super(TestMapping, self).__init__()
|
||||||
|
self.data = {'password': 'shhh',
|
||||||
|
'foo': 'bar',
|
||||||
|
}
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.data[key]
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self.data.__iter__()
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.data)
|
||||||
|
|
||||||
|
|
||||||
|
class NestedMapping(TestMapping):
|
||||||
|
"""Test class that contains an instance of TestMapping"""
|
||||||
|
def __init__(self):
|
||||||
|
super(NestedMapping, self).__init__()
|
||||||
|
self.data = {'nested': TestMapping()}
|
||||||
|
|
||||||
|
|
||||||
class MaskDictionaryPasswordTestCase(test_base.BaseTestCase):
|
class MaskDictionaryPasswordTestCase(test_base.BaseTestCase):
|
||||||
|
|
||||||
def test_dictionary(self):
|
def test_dictionary(self):
|
||||||
|
@ -696,6 +722,21 @@ class MaskDictionaryPasswordTestCase(test_base.BaseTestCase):
|
||||||
strutils.mask_dict_password(payload)
|
strutils.mask_dict_password(payload)
|
||||||
self.assertEqual(pristine, payload)
|
self.assertEqual(pristine, payload)
|
||||||
|
|
||||||
|
def test_non_dict(self):
|
||||||
|
expected = {'password': '***',
|
||||||
|
'foo': 'bar',
|
||||||
|
}
|
||||||
|
payload = TestMapping()
|
||||||
|
self.assertEqual(expected, strutils.mask_dict_password(payload))
|
||||||
|
|
||||||
|
def test_nested_non_dict(self):
|
||||||
|
expected = {'nested': {'password': '***',
|
||||||
|
'foo': 'bar',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payload = NestedMapping()
|
||||||
|
self.assertEqual(expected, strutils.mask_dict_password(payload))
|
||||||
|
|
||||||
|
|
||||||
class IsIntLikeTestCase(test_base.BaseTestCase):
|
class IsIntLikeTestCase(test_base.BaseTestCase):
|
||||||
def test_is_int_like_true(self):
|
def test_is_int_like_true(self):
|
||||||
|
|
Loading…
Reference in New Issue