Skip to content

Commit 35e299b

Browse files
committed
fix auth cache to allow for username in index url
1 parent 0b6316c commit 35e299b

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed

news/10269.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix the auth credential cache to allow for the case in which
2+
the index url contains the username, but the password comes
3+
from an external source, such as keyring.

src/pip/_internal/network/auth.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,16 @@ def _get_url_and_credentials(
179179
# Try to get credentials from original url
180180
username, password = self._get_new_credentials(original_url)
181181

182-
# If credentials not found, use any stored credentials for this netloc
183-
if username is None and password is None:
184-
username, password = self.passwords.get(netloc, (None, None))
182+
# If credentials not found, use any stored credentials for this netloc.
183+
# Do this if either the username or the password is missing.
184+
# This accounts for the situation in which the user has specified
185+
# the username in the index url, but the password comes from keyring.
186+
if (username is None or password is None) and netloc in self.passwords:
187+
un, pw = self.passwords[netloc]
188+
# It is possible that the cached credentials are for a different username,
189+
# in which case the cache should be ignored.
190+
if username is None or username == un:
191+
username, password = un, pw
185192

186193
if username is not None or password is not None:
187194
# Convert the username and password if they're None, so that

tests/unit/test_network_auth.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ def test_get_credentials_uses_cached_credentials():
7474
assert got == expected
7575

7676

77+
def test_get_credentials_uses_cached_credentials_only_username():
78+
auth = MultiDomainBasicAuth()
79+
auth.passwords['example.com'] = ('user', 'pass')
80+
81+
got = auth._get_url_and_credentials("http://[email protected]/path")
82+
expected = ('http://example.com/path', 'user', 'pass')
83+
assert got == expected
84+
85+
7786
def test_get_index_url_credentials():
7887
auth = MultiDomainBasicAuth(index_urls=[
7988
"http://foo:[email protected]/path"

0 commit comments

Comments
 (0)