diff options
author | Zuul <zuul@review.openstack.org> | 2019-01-08 00:08:03 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2019-01-08 00:08:03 +0000 |
commit | 380bf5a47ef1bceb8b2b1c5c9f15e6c7cfdc038d (patch) | |
tree | 6931062ed48f2f7c9e1fb53baba6a376462d0aff | |
parent | 7e429593b9f54b7587008fc356671ceaa1fdd4c7 (diff) | |
parent | ddc436925887b6ece4aba19a36e53ede0b22ae21 (diff) | |
download | oslo-utils-380bf5a47ef1bceb8b2b1c5c9f15e6c7cfdc038d.tar.gz |
Merge "Support non-dict mappings in mask_dict_password"3.40.0
-rw-r--r-- | oslo_utils/strutils.py | 7 | ||||
-rw-r--r-- | oslo_utils/tests/test_strutils.py | 41 |
2 files changed, 45 insertions, 3 deletions
diff --git a/oslo_utils/strutils.py b/oslo_utils/strutils.py index ebcc104..d7b104d 100644 --- a/oslo_utils/strutils.py +++ b/oslo_utils/strutils.py @@ -17,6 +17,7 @@ System-level utilities and helper functions. """ +import collections import math import re import unicodedata @@ -390,12 +391,12 @@ def mask_dict_password(dictionary, secret="***"): # nosec """ - if not isinstance(dictionary, dict): - raise TypeError("Expected a dictionary, got %s instead." + if not isinstance(dictionary, collections.Mapping): + raise TypeError("Expected a Mapping, got %s instead." % type(dictionary)) out = {} for k, v in dictionary.items(): - if isinstance(v, dict): + if isinstance(v, collections.Mapping): out[k] = mask_dict_password(v, secret=secret) continue # NOTE(jlvillal): Check to see if anything in the dictionary 'key' diff --git a/oslo_utils/tests/test_strutils.py b/oslo_utils/tests/test_strutils.py index 301b619..e015b2e 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 collections import copy import math @@ -613,6 +614,31 @@ class MaskPasswordTestCase(test_base.BaseTestCase): 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): def test_dictionary(self): @@ -696,6 +722,21 @@ class MaskDictionaryPasswordTestCase(test_base.BaseTestCase): strutils.mask_dict_password(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): def test_is_int_like_true(self): |