diff --git a/src/python_inspector/utils.py b/src/python_inspector/utils.py index 1548ac0b..14d2a98b 100644 --- a/src/python_inspector/utils.py +++ b/src/python_inspector/utils.py @@ -16,20 +16,28 @@ from typing import NamedTuple from typing import Optional +from urllib.parse import urlparse + import aiohttp import requests def get_netrc_auth(url, netrc): """ - Return login and password if url is in netrc + Return login and password if either the hostname is in netrc or a default is set in netrc else return login and password as None """ + hostname = urlparse(url).hostname hosts = netrc.hosts - if url in hosts: - url_auth = hosts.get(url) + if hostname in hosts: + url_auth = hosts.get(hostname) # netrc returns a tuple of (login, account, password) return (url_auth[0], url_auth[2]) + + if "default" in hosts: + default_auth = hosts.get("default") + return (default_auth[0], default_auth[2]) + return (None, None) diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py index f2757cd6..0da998cc 100644 --- a/src/python_inspector/utils_pypi.py +++ b/src/python_inspector/utils_pypi.py @@ -1598,6 +1598,10 @@ async def fetch_links( name using the `index_url` of this repository. """ package_url = f"{self.index_url}/{normalized_name}" + + if not package_url.endswith("/"): + package_url += "/" + text, _ = await CACHE.get( path_or_url=package_url, credentials=self.credentials, @@ -1797,7 +1801,10 @@ async def get_remote_file_content( auth = None if credentials: - auth = (credentials.get("login"), credentials.get("password")) + login = credentials.get("login") + password = credentials.get("password") + if login and password: + auth = aiohttp.BasicAuth(login, password) async with aiohttp.ClientSession() as session: async with session.get(url, allow_redirects=True, headers=headers, auth=auth) as response: diff --git a/tests/data/test-commented.netrc b/tests/data/test-commented.netrc index 858b48fb..2f482bb1 100644 --- a/tests/data/test-commented.netrc +++ b/tests/data/test-commented.netrc @@ -1,2 +1,2 @@ -machine https://pyp2.org/simple login test password test123 -# machine https://pyp1.org/simple login test password test123 \ No newline at end of file +machine pyp2.org login test password test123 +# machine pyp1.org login test password test123 \ No newline at end of file diff --git a/tests/data/test-default.netrc b/tests/data/test-default.netrc new file mode 100644 index 00000000..c68aa0f0 --- /dev/null +++ b/tests/data/test-default.netrc @@ -0,0 +1,2 @@ +machine example.com login test password test123 +default login defaultuser password defaultpass diff --git a/tests/data/test.netrc b/tests/data/test.netrc index d886b2dc..9b1b45cd 100644 --- a/tests/data/test.netrc +++ b/tests/data/test.netrc @@ -1 +1,2 @@ -machine https://pyp1.org/simple login test password test123 \ No newline at end of file +machine pyp1.org login test password test123 +machine subdomain.example.com login subdomain-user password subdomain-secret \ No newline at end of file diff --git a/tests/test_utils.py b/tests/test_utils.py index 17e7e897..d9c0fe5c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -35,6 +35,25 @@ def test_get_netrc_auth(): netrc_file = test_env.get_test_loc("test.netrc") parsed_netrc = netrc(netrc_file) assert get_netrc_auth(url="https://pyp1.org/simple", netrc=parsed_netrc) == ("test", "test123") + assert get_netrc_auth(url="https://pyp1.org/different/path", netrc=parsed_netrc) == ( + "test", + "test123", + ) + assert get_netrc_auth(url="https://pyp1.org", netrc=parsed_netrc) == ("test", "test123") + + +def test_get_netrc_auth_with_ports_and_schemes(): + netrc_file = test_env.get_test_loc("test.netrc") + parsed_netrc = netrc(netrc_file) + + assert get_netrc_auth(url="https://pyp1.org:443/path", netrc=parsed_netrc) == ( + "test", + "test123", + ) + assert get_netrc_auth(url="http://pyp1.org:80/simple", netrc=parsed_netrc) == ( + "test", + "test123", + ) def test_get_commented_netrc_auth(): @@ -49,6 +68,34 @@ def test_get_netrc_auth_with_no_matching_url(): assert get_netrc_auth(url="https://pypi2.org/simple", netrc=parsed_netrc) == (None, None) +def test_get_netrc_auth_with_with_subdomains(): + netrc_file = test_env.get_test_loc("test.netrc") + parsed_netrc = netrc(netrc_file) + + assert get_netrc_auth(url="https://subdomain.example.com/simple", netrc=parsed_netrc) == ( + "subdomain-user", + "subdomain-secret", + ) + assert get_netrc_auth(url="https://another.example.com/simple", netrc=parsed_netrc) == ( + None, + None, + ) + + +def test_get_netrc_auth_with_default(): + netrc_file = test_env.get_test_loc("test-default.netrc") + parsed_netrc = netrc(netrc_file) + + assert get_netrc_auth(url="https://example.com/simple", netrc=parsed_netrc) == ( + "test", + "test123", + ) + assert get_netrc_auth(url="https://non-existing.org/simple", netrc=parsed_netrc) == ( + "defaultuser", + "defaultpass", + ) + + @pytest.mark.asyncio @pytest.mark.skipif(sys.version_info < (3, 8), reason="requires python3.8 or higher") @mock.patch("python_inspector.utils_pypi.CACHE.get")