diff --git a/src/poetry/utils/password_manager.py b/src/poetry/utils/password_manager.py index 383a4927a5d..f40ac4d1355 100644 --- a/src/poetry/utils/password_manager.py +++ b/src/poetry/utils/password_manager.py @@ -195,18 +195,25 @@ def delete_pypi_token(self, repo_name: str) -> None: def get_http_auth(self, repo_name: str) -> dict[str, str | None] | None: username = self._config.get(f"http-basic.{repo_name}.username") password = self._config.get(f"http-basic.{repo_name}.password") - if not username and not password: + + # we only return None if both values are None or "" + # password can be None at this stage with the username "" + if (username is password is None) or (username == password == ""): return None if not password: if self.use_keyring: password = self.keyring.get_password(repo_name, username) - else: + elif not username: + # at this tage if username is "" or None, auth is invalid return None + if not username and not password: + return None + return { - "username": username, - "password": password, + "username": username or "", + "password": password or "", } def set_http_password(self, repo_name: str, username: str, password: str) -> None: diff --git a/tests/utils/test_password_manager.py b/tests/utils/test_password_manager.py index 836ca004478..00058e46513 100644 --- a/tests/utils/test_password_manager.py +++ b/tests/utils/test_password_manager.py @@ -36,19 +36,36 @@ def test_set_http_password( assert "password" not in auth +@pytest.mark.parametrize( + ("username", "password", "is_valid"), + [ + ("bar", "baz", True), + ("", "baz", True), + ("bar", "", True), + ("", "", False), + ], +) def test_get_http_auth( - config: Config, with_simple_keyring: None, dummy_keyring: DummyBackend + username: str, + password: str, + is_valid: bool, + config: Config, + with_simple_keyring: None, + dummy_keyring: DummyBackend, ) -> None: - dummy_keyring.set_password("poetry-repository-foo", "bar", "baz") - config.auth_config_source.add_property("http-basic.foo", {"username": "bar"}) + dummy_keyring.set_password("poetry-repository-foo", username, password) + config.auth_config_source.add_property("http-basic.foo", {"username": username}) manager = PasswordManager(config) assert PoetryKeyring.is_available() auth = manager.get_http_auth("foo") - assert auth is not None - assert auth["username"] == "bar" - assert auth["password"] == "baz" + if is_valid: + assert auth is not None + assert auth["username"] == username + assert auth["password"] == password + else: + assert auth is None def test_delete_http_password( @@ -113,20 +130,36 @@ def test_set_http_password_with_unavailable_backend( assert auth["password"] == "baz" +@pytest.mark.parametrize( + ("username", "password", "is_valid"), + [ + ("bar", "baz", True), + ("", "baz", True), + ("bar", "", True), + ("", "", False), + ], +) def test_get_http_auth_with_unavailable_backend( - config: Config, with_fail_keyring: None + username: str, + password: str, + is_valid: bool, + config: Config, + with_fail_keyring: None, ) -> None: config.auth_config_source.add_property( - "http-basic.foo", {"username": "bar", "password": "baz"} + "http-basic.foo", {"username": username, "password": password} ) manager = PasswordManager(config) assert not PoetryKeyring.is_available() auth = manager.get_http_auth("foo") - assert auth is not None - assert auth["username"] == "bar" - assert auth["password"] == "baz" + if is_valid: + assert auth is not None + assert auth["username"] == username + assert auth["password"] == password + else: + assert auth is None def test_delete_http_password_with_unavailable_backend(