From 437cd55ac1425aba87ac31acae46c47cc318c592 Mon Sep 17 00:00:00 2001 From: Pawel Tetera Date: Tue, 25 Mar 2025 20:10:44 +0000 Subject: [PATCH] Add --debug-with-secrets and truncate by default Previously, data which may be considered sensitive such as the X-Auth-Token or X-Storage-Token headers is hidden for the --info option but not --debug. This patch enables truncating of LOGGER_SENSITIVE_HEADERS by default for --debug so that end users can share debug output more easily without having to manually sanitize logs and adds unit tests for it. A separate --debug-with-secrets option is provided should explicit printing of auth tokens be desirable, mimicking the old behaviour. --debug-insecure, suggested on launchpad naming was considered as well however a --insecure param which skips SSL verification already exists and does something else. The --with-secrets suffix should also help make the purpose of this param explicit enough. Closes-Bug: #2061011 Closes-Bug: #2061012 Change-Id: Ie64b0f496c016a5871de7ada84acb572c008d127 (cherry picked from commit 9e67409f33d708f2beafb21cafeff30e9a7ff637) --- swiftclient/shell.py | 18 +++++++++++++----- test/unit/test_shell.py | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/swiftclient/shell.py b/swiftclient/shell.py index 1dc8d2f4..23691f25 100755 --- a/swiftclient/shell.py +++ b/swiftclient/shell.py @@ -1638,14 +1638,17 @@ def prompt_for_password(): def parse_args(parser, args, enforce_requires=True): options, args = parser.parse_known_args(args or ['-h']) options = vars(options) - if enforce_requires and (options.get('debug') or options.get('info')): + if enforce_requires and (options.get('debug') or + options.get('debug_with_secrets') or + options.get('info')): logging.getLogger("swiftclient") - if options.get('debug'): + if options.get('debug') or options.get('debug_with_secrets'): logging.basicConfig(level=logging.DEBUG) logging.getLogger('iso8601').setLevel(logging.WARNING) - client_logger_settings['redact_sensitive_headers'] = False elif options.get('info'): logging.basicConfig(level=logging.INFO) + client_logger_settings['redact_sensitive_headers'] = not ( + enforce_requires and options.get('debug_with_secrets')) if args and options.get('help'): _help = globals().get('st_%s_help' % args[0]) @@ -1732,6 +1735,11 @@ def add_default_args(parser): default=False, help='Show the curl commands and ' 'results of all http queries regardless of result ' 'status.') + parser.add_argument('--debug-with-secrets', action='store_true', + dest='debug_with_secrets', default=False, + help='Show the curl commands and ' + 'results of all http queries regardless of result ' + 'status (without truncating auth tokens).') parser.add_argument('--info', action='store_true', dest='info', default=False, help='Show the curl commands and ' 'results of all http queries which return an error.') @@ -1958,8 +1966,8 @@ def main(arguments=None): parser = argparse.ArgumentParser( add_help=False, formatter_class=HelpFormatter, usage=''' %(prog)s [--version] [--help] [--os-help] [--snet] [--verbose] - [--debug] [--info] [--quiet] [--auth ] - [--auth-version | + [--debug] [--debug-with-secrets] [--info] [--quiet] + [--auth ] [--auth-version | --os-identity-api-version ] [--user ] [--key ] [--retries ] diff --git a/test/unit/test_shell.py b/test/unit/test_shell.py index e4e19012..b2b34431 100644 --- a/test/unit/test_shell.py +++ b/test/unit/test_shell.py @@ -2647,10 +2647,23 @@ class TestDebugAndInfoOptions(unittest.TestCase): argv = ["", "stat", "--info"] swiftclient.shell.main(argv) mock_logging.assert_called_with(level=logging.INFO) + self.assertTrue( + swiftclient.logger_settings.get('redact_sensitive_headers') + ) argv = ["", "stat", "--debug"] swiftclient.shell.main(argv) mock_logging.assert_called_with(level=logging.DEBUG) + self.assertTrue( + swiftclient.logger_settings.get('redact_sensitive_headers') + ) + + argv = ["", "stat", "--debug-with-secrets"] + swiftclient.shell.main(argv) + mock_logging.assert_called_with(level=logging.DEBUG) + self.assertFalse( + swiftclient.logger_settings.get('redact_sensitive_headers') + ) @mock.patch('logging.basicConfig') @mock.patch('swiftclient.service.Connection') @@ -2660,7 +2673,13 @@ class TestDebugAndInfoOptions(unittest.TestCase): ["", "--info", "stat", "--debug"], ["", "--debug", "stat", "--info"], ["", "--info", "--debug", "stat"], - ["", "--debug", "--info", "stat"]) + ["", "--debug", "--info", "stat"], + ["", "stat", "--info", "--debug-with-secrets"], + ["", "stat", "--debug-with-secrets", "--info"], + ["", "--info", "stat", "--debug-with-secrets"], + ["", "--debug-with-secrets", "stat", "--info"], + ["", "--info", "--debug-with-secrets", "stat"], + ["", "--debug-with-secrets", "--info", "stat"]) for argv in argv_scenarios: mock_logging.reset_mock() swiftclient.shell.main(argv)