From 8f821866d66b49f1acb3dfdbb18d21576f024eab Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Wed, 25 Nov 2020 21:16:41 +0200 Subject: [PATCH 1/2] Redact auth from URL in UpdatingDefaultsHelpFormatter --- news/9160.bugfix.rst | 1 + src/pip/_internal/cli/parser.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 news/9160.bugfix.rst diff --git a/news/9160.bugfix.rst b/news/9160.bugfix.rst new file mode 100644 index 00000000000..fad6dc1f0d2 --- /dev/null +++ b/news/9160.bugfix.rst @@ -0,0 +1 @@ +Redact auth from URL in help message. diff --git a/src/pip/_internal/cli/parser.py b/src/pip/_internal/cli/parser.py index b6b78318a7a..ea3b383e2f7 100644 --- a/src/pip/_internal/cli/parser.py +++ b/src/pip/_internal/cli/parser.py @@ -17,6 +17,7 @@ from pip._internal.cli.status_codes import UNKNOWN_ERROR from pip._internal.configuration import Configuration, ConfigurationError from pip._internal.utils.compat import get_terminal_size +from pip._internal.utils.misc import redact_auth_from_url logger = logging.getLogger(__name__) @@ -106,12 +107,22 @@ class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): This is updates the defaults before expanding them, allowing them to show up correctly in the help listing. + + Also redact auth from url type options """ def expand_default(self, option): + default_value = None if self.parser is not None: self.parser._update_defaults(self.parser.defaults) - return optparse.IndentedHelpFormatter.expand_default(self, option) + default_value = self.parser.defaults.get(option.dest) + help_text = optparse.IndentedHelpFormatter.expand_default(self, option) + + if default_value and option.metavar == 'URL': + help_text = help_text.replace( + default_value, redact_auth_from_url(default_value)) + + return help_text class CustomOptionParser(optparse.OptionParser): From 4f8dfcf29d2527e3087c401b405b6c59b401cbad Mon Sep 17 00:00:00 2001 From: Noah Gorny Date: Thu, 26 Nov 2020 15:15:21 +0200 Subject: [PATCH 2/2] tests: help: Test that auth is redacted from url in help menu --- tests/functional/test_help.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/functional/test_help.py b/tests/functional/test_help.py index 00a395006b7..9c2508abb51 100644 --- a/tests/functional/test_help.py +++ b/tests/functional/test_help.py @@ -64,6 +64,16 @@ def test_help_command_should_exit_status_error_when_cmd_does_not_exist(script): assert result.returncode == ERROR +def test_help_command_redact_auth_from_url(script): + """ + Test `help` on various subcommands redact auth from url + """ + script.environ['PIP_INDEX_URL'] = 'https://user:secret@example.com' + result = script.pip('install', '--help') + assert result.returncode == SUCCESS + assert 'secret' not in result.stdout + + def test_help_commands_equally_functional(in_memory_pip): """ Test if `pip help` and 'pip --help' behave the same way.