mirror of https://github.com/pypa/pip
Fix handling of tokens (single part credentials) in URLs (#6818)
This commit is contained in:
parent
4601a8d83f
commit
f41f747f8b
|
@ -0,0 +1 @@
|
||||||
|
Fix handling of tokens (single part credentials) in URLs.
|
|
@ -295,7 +295,7 @@ class MultiDomainBasicAuth(AuthBase):
|
||||||
logger.debug("Found credentials in keyring for %s", netloc)
|
logger.debug("Found credentials in keyring for %s", netloc)
|
||||||
return kr_auth
|
return kr_auth
|
||||||
|
|
||||||
return None, None
|
return username, password
|
||||||
|
|
||||||
def _get_url_and_credentials(self, original_url):
|
def _get_url_and_credentials(self, original_url):
|
||||||
"""Return the credentials to use for the provided URL.
|
"""Return the credentials to use for the provided URL.
|
||||||
|
@ -312,15 +312,29 @@ class MultiDomainBasicAuth(AuthBase):
|
||||||
# Use any stored credentials that we have for this netloc
|
# Use any stored credentials that we have for this netloc
|
||||||
username, password = self.passwords.get(netloc, (None, None))
|
username, password = self.passwords.get(netloc, (None, None))
|
||||||
|
|
||||||
# If nothing cached, acquire new credentials without prompting
|
if username is None and password is None:
|
||||||
# the user (e.g. from netrc, keyring, or similar).
|
# No stored credentials. Acquire new credentials without prompting
|
||||||
if username is None or password is None:
|
# the user. (e.g. from netrc, keyring, or the URL itself)
|
||||||
username, password = self._get_new_credentials(original_url)
|
username, password = self._get_new_credentials(original_url)
|
||||||
|
|
||||||
if username is not None and password is not None:
|
if username is not None or password is not None:
|
||||||
# Store the username and password
|
# Convert the username and password if they're None, so that
|
||||||
|
# this netloc will show up as "cached" in the conditional above.
|
||||||
|
# Further, HTTPBasicAuth doesn't accept None, so it makes sense to
|
||||||
|
# cache the value that is going to be used.
|
||||||
|
username = username or ""
|
||||||
|
password = password or ""
|
||||||
|
|
||||||
|
# Store any acquired credentials.
|
||||||
self.passwords[netloc] = (username, password)
|
self.passwords[netloc] = (username, password)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
# Credentials were found
|
||||||
|
(username is not None and password is not None) or
|
||||||
|
# Credentials were not found
|
||||||
|
(username is None and password is None)
|
||||||
|
), "Could not load credentials from url: {}".format(original_url)
|
||||||
|
|
||||||
return url, username, password
|
return url, username, password
|
||||||
|
|
||||||
def __call__(self, req):
|
def __call__(self, req):
|
||||||
|
|
|
@ -483,18 +483,53 @@ class TestPipSession:
|
||||||
assert not hasattr(session.adapters["https://example.com/"], "cache")
|
assert not hasattr(session.adapters["https://example.com/"], "cache")
|
||||||
|
|
||||||
|
|
||||||
def test_get_credentials():
|
@pytest.mark.parametrize(["input_url", "url", "username", "password"], [
|
||||||
|
(
|
||||||
|
"http://user%40email.com:password@example.com/path",
|
||||||
|
"http://example.com/path",
|
||||||
|
"user@email.com",
|
||||||
|
"password",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"http://username:password@example.com/path",
|
||||||
|
"http://example.com/path",
|
||||||
|
"username",
|
||||||
|
"password",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"http://token@example.com/path",
|
||||||
|
"http://example.com/path",
|
||||||
|
"token",
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"http://example.com/path",
|
||||||
|
"http://example.com/path",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
def test_get_credentials_parses_correctly(input_url, url, username, password):
|
||||||
auth = MultiDomainBasicAuth()
|
auth = MultiDomainBasicAuth()
|
||||||
get = auth._get_url_and_credentials
|
get = auth._get_url_and_credentials
|
||||||
|
|
||||||
# Check URL parsing
|
# Check URL parsing
|
||||||
assert get("http://foo:bar@example.com/path") \
|
assert get(input_url) == (url, username, password)
|
||||||
== ('http://example.com/path', 'foo', 'bar')
|
assert (
|
||||||
assert auth.passwords['example.com'] == ('foo', 'bar')
|
# There are no credentials in the URL
|
||||||
|
(username is None and password is None) or
|
||||||
|
# Credentials were found and "cached" appropriately
|
||||||
|
auth.passwords['example.com'] == (username, password)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_credentials_uses_cached_credentials():
|
||||||
|
auth = MultiDomainBasicAuth()
|
||||||
auth.passwords['example.com'] = ('user', 'pass')
|
auth.passwords['example.com'] = ('user', 'pass')
|
||||||
assert get("http://foo:bar@example.com/path") \
|
|
||||||
== ('http://example.com/path', 'user', 'pass')
|
got = auth._get_url_and_credentials("http://foo:bar@example.com/path")
|
||||||
|
expected = ('http://example.com/path', 'user', 'pass')
|
||||||
|
assert got == expected
|
||||||
|
|
||||||
|
|
||||||
def test_get_index_url_credentials():
|
def test_get_index_url_credentials():
|
||||||
|
|
Loading…
Reference in New Issue