summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--news/6891.feature1
-rw-r--r--src/pip/_internal/cli/cmdoptions.py4
-rw-r--r--src/pip/_internal/index.py6
-rw-r--r--src/pip/_internal/models/link.py6
-rw-r--r--src/pip/_internal/models/search_scope.py6
-rw-r--r--src/pip/_internal/req/req_install.py6
-rw-r--r--src/pip/_internal/utils/misc.py19
-rw-r--r--tests/unit/test_utils.py10
8 files changed, 33 insertions, 25 deletions
diff --git a/news/6891.feature b/news/6891.feature
new file mode 100644
index 000000000..4d08eedfb
--- /dev/null
+++ b/news/6891.feature
@@ -0,0 +1 @@
+Redact single-part login credentials from URLs in log messages.
diff --git a/src/pip/_internal/cli/cmdoptions.py b/src/pip/_internal/cli/cmdoptions.py
index 1bfecef54..155211903 100644
--- a/src/pip/_internal/cli/cmdoptions.py
+++ b/src/pip/_internal/cli/cmdoptions.py
@@ -27,7 +27,7 @@ from pip._internal.models.index import PyPI
from pip._internal.models.search_scope import SearchScope
from pip._internal.models.target_python import TargetPython
from pip._internal.utils.hashes import STRONG_HASHES
-from pip._internal.utils.misc import redact_password_from_url
+from pip._internal.utils.misc import redact_auth_from_url
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
from pip._internal.utils.ui import BAR_TYPES
@@ -369,7 +369,7 @@ def make_search_scope(options, suppress_no_index=False):
if options.no_index and not suppress_no_index:
logger.debug(
'Ignoring indexes: %s',
- ','.join(redact_password_from_url(url) for url in index_urls),
+ ','.join(redact_auth_from_url(url) for url in index_urls),
)
index_urls = []
diff --git a/src/pip/_internal/index.py b/src/pip/_internal/index.py
index 93c198433..ba44e7bb4 100644
--- a/src/pip/_internal/index.py
+++ b/src/pip/_internal/index.py
@@ -40,7 +40,7 @@ from pip._internal.utils.misc import (
WHEEL_EXTENSION,
build_netloc,
path_to_url,
- redact_password_from_url,
+ redact_auth_from_url,
)
from pip._internal.utils.packaging import check_requires_python
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
@@ -154,7 +154,7 @@ def _get_html_response(url, session):
if _is_url_like_archive(url):
_ensure_html_response(url, session=session)
- logger.debug('Getting page %s', redact_password_from_url(url))
+ logger.debug('Getting page %s', redact_auth_from_url(url))
resp = session.get(
url,
@@ -1381,7 +1381,7 @@ class HTMLPage(object):
self.headers = headers
def __str__(self):
- return redact_password_from_url(self.url)
+ return redact_auth_from_url(self.url)
def iter_links(self):
# type: () -> Iterable[Link]
diff --git a/src/pip/_internal/models/link.py b/src/pip/_internal/models/link.py
index 56ad2a5be..2a3c605e5 100644
--- a/src/pip/_internal/models/link.py
+++ b/src/pip/_internal/models/link.py
@@ -6,7 +6,7 @@ from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._internal.utils.misc import (
WHEEL_EXTENSION,
path_to_url,
- redact_password_from_url,
+ redact_auth_from_url,
split_auth_from_netloc,
splitext,
)
@@ -68,10 +68,10 @@ class Link(KeyBasedCompareMixin):
else:
rp = ''
if self.comes_from:
- return '%s (from %s)%s' % (redact_password_from_url(self._url),
+ return '%s (from %s)%s' % (redact_auth_from_url(self._url),
self.comes_from, rp)
else:
- return redact_password_from_url(str(self._url))
+ return redact_auth_from_url(str(self._url))
def __repr__(self):
return '<Link %s>' % self
diff --git a/src/pip/_internal/models/search_scope.py b/src/pip/_internal/models/search_scope.py
index 621524495..5d667deef 100644
--- a/src/pip/_internal/models/search_scope.py
+++ b/src/pip/_internal/models/search_scope.py
@@ -8,7 +8,7 @@ from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._internal.models.index import PyPI
from pip._internal.utils.compat import HAS_TLS
-from pip._internal.utils.misc import normalize_path, redact_password_from_url
+from pip._internal.utils.misc import normalize_path, redact_auth_from_url
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
if MYPY_CHECK_RUNNING:
@@ -80,12 +80,12 @@ class SearchScope(object):
if self.index_urls and self.index_urls != [PyPI.simple_url]:
lines.append(
'Looking in indexes: {}'.format(', '.join(
- redact_password_from_url(url) for url in self.index_urls))
+ redact_auth_from_url(url) for url in self.index_urls))
)
if self.find_links:
lines.append(
'Looking in links: {}'.format(', '.join(
- redact_password_from_url(url) for url in self.find_links))
+ redact_auth_from_url(url) for url in self.find_links))
)
return '\n'.join(lines)
diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py
index 264fade4c..a72d4dd70 100644
--- a/src/pip/_internal/req/req_install.py
+++ b/src/pip/_internal/req/req_install.py
@@ -39,7 +39,7 @@ from pip._internal.utils.misc import (
ensure_dir,
get_installed_version,
hide_url,
- redact_password_from_url,
+ redact_auth_from_url,
rmtree,
)
from pip._internal.utils.packaging import get_metadata
@@ -170,9 +170,9 @@ class InstallRequirement(object):
if self.req:
s = str(self.req)
if self.link:
- s += ' from %s' % redact_password_from_url(self.link.url)
+ s += ' from %s' % redact_auth_from_url(self.link.url)
elif self.link:
- s = redact_password_from_url(self.link.url)
+ s = redact_auth_from_url(self.link.url)
else:
s = '<InstallRequirement>'
if self.satisfied_by is not None:
diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py
index d19df9459..f6e6e291c 100644
--- a/src/pip/_internal/utils/misc.py
+++ b/src/pip/_internal/utils/misc.py
@@ -1194,15 +1194,22 @@ def split_auth_from_netloc(netloc):
def redact_netloc(netloc):
# type: (str) -> str
"""
- Replace the password in a netloc with "****", if it exists.
+ Replace the sensitive data in a netloc with "****", if it exists.
- For example, "user:pass@example.com" returns "user:****@example.com".
+ For example:
+ - "user:pass@example.com" returns "user:****@example.com"
+ - "accesstoken@example.com" returns "****@example.com"
"""
netloc, (user, password) = split_auth_from_netloc(netloc)
if user is None:
return netloc
- password = '' if password is None else ':****'
- return '{user}{password}@{netloc}'.format(user=urllib_parse.quote(user),
+ if password is None:
+ user = '****'
+ password = ''
+ else:
+ user = urllib_parse.quote(user)
+ password = ':****'
+ return '{user}{password}@{netloc}'.format(user=user,
password=password,
netloc=netloc)
@@ -1254,7 +1261,7 @@ def remove_auth_from_url(url):
return _transform_url(url, _get_netloc)[0]
-def redact_password_from_url(url):
+def redact_auth_from_url(url):
# type: (str) -> str
"""Replace the password in a given url with ****."""
return _transform_url(url, _redact_netloc)[0]
@@ -1302,7 +1309,7 @@ def hide_value(value):
def hide_url(url):
# type: (str) -> HiddenText
- redacted = redact_password_from_url(url)
+ redacted = redact_auth_from_url(url)
return HiddenText(url, redacted=redacted)
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
index 51cf2a23a..6c1ad16f8 100644
--- a/tests/unit/test_utils.py
+++ b/tests/unit/test_utils.py
@@ -55,8 +55,8 @@ from pip._internal.utils.misc import (
parse_netloc,
path_to_display,
path_to_url,
+ redact_auth_from_url,
redact_netloc,
- redact_password_from_url,
remove_auth_from_url,
rmtree,
split_auth_from_netloc,
@@ -1332,7 +1332,7 @@ def test_split_auth_netloc_from_url(url, expected):
# Test a basic case.
('example.com', 'example.com'),
# Test with username and no password.
- ('user@example.com', 'user@example.com'),
+ ('accesstoken@example.com', '****@example.com'),
# Test with username and password.
('user:pass@example.com', 'user:****@example.com'),
# Test with username and empty password.
@@ -1371,7 +1371,7 @@ def test_remove_auth_from_url(auth_url, expected_url):
@pytest.mark.parametrize('auth_url, expected_url', [
- ('https://user@example.com/abc', 'https://user@example.com/abc'),
+ ('https://accesstoken@example.com/abc', 'https://****@example.com/abc'),
('https://user:password@example.com', 'https://user:****@example.com'),
('https://user:@example.com', 'https://user:****@example.com'),
('https://example.com', 'https://example.com'),
@@ -1379,8 +1379,8 @@ def test_remove_auth_from_url(auth_url, expected_url):
('https://user%3Aname:%23%40%5E@example.com',
'https://user%3Aname:****@example.com'),
])
-def test_redact_password_from_url(auth_url, expected_url):
- url = redact_password_from_url(auth_url)
+def test_redact_auth_from_url(auth_url, expected_url):
+ url = redact_auth_from_url(auth_url)
assert url == expected_url