From c990ee02faa9f88e07a27af12eae397e7e8097dc Mon Sep 17 00:00:00 2001
From: Ryan Rossiter <rlrossit@us.ibm.com>
Date: Thu, 20 Aug 2015 20:47:42 +0000
Subject: [PATCH] Mask passwords when logging messages

When logging a message, any secrets and passwords should be masked. This
uses oslo_utils.strutils to mask any passwords that are to be logged.

Change-Id: I263d44c0f2e900c5f6e210cbd7ec56e48d0d5bb2
Closes-Bug: #1487038
---
 oslo_messaging/notify/_impl_log.py           |  3 ++-
 oslo_messaging/tests/notify/test_notifier.py | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/oslo_messaging/notify/_impl_log.py b/oslo_messaging/notify/_impl_log.py
index 400f556f5..dc2364c77 100644
--- a/oslo_messaging/notify/_impl_log.py
+++ b/oslo_messaging/notify/_impl_log.py
@@ -18,6 +18,7 @@
 import logging
 
 from oslo_serialization import jsonutils
+from oslo_utils import strutils
 
 from oslo_messaging.notify import notifier
 
@@ -38,4 +39,4 @@ class LogDriver(notifier._Driver):
                                               message['event_type']))
         method = getattr(logger, priority.lower(), None)
         if method:
-            method(jsonutils.dumps(message))
+            method(strutils.mask_password(jsonutils.dumps(message)))
diff --git a/oslo_messaging/tests/notify/test_notifier.py b/oslo_messaging/tests/notify/test_notifier.py
index 946a72334..d75288d0d 100644
--- a/oslo_messaging/tests/notify/test_notifier.py
+++ b/oslo_messaging/tests/notify/test_notifier.py
@@ -20,6 +20,7 @@ import uuid
 
 import fixtures
 from oslo_serialization import jsonutils
+from oslo_utils import strutils
 from oslo_utils import timeutils
 from stevedore import dispatch
 from stevedore import extension
@@ -317,6 +318,22 @@ class TestLogNotifier(test_utils.BaseTestCase):
         msg = {'event_type': 'foo'}
         driver.notify(None, msg, "sample", None)
 
+    def test_mask_passwords(self):
+        # Ensure that passwords are masked with notifications
+        driver = _impl_log.LogDriver(None, None, None)
+        logger = mock.MagicMock()
+        logger.info = mock.MagicMock()
+        message = {'password': 'passw0rd', 'event_type': 'foo'}
+        json_str = jsonutils.dumps(message)
+        mask_str = strutils.mask_password(json_str)
+
+
+        with mock.patch.object(logging, 'getLogger') as gl:
+            gl.return_value = logger
+            driver.notify(None, message, 'info', 0)
+
+        logger.info.assert_called_once_with(mask_str)
+
 
 class TestRoutingNotifier(test_utils.BaseTestCase):
     def setUp(self):