From d4752217d6bb16ec94aba07206e86e805576a068 Mon Sep 17 00:00:00 2001 From: Martin Stolle Date: Wed, 25 Sep 2024 10:26:04 +0200 Subject: [PATCH] Support username and password from keyring --- src/hatch/publish/auth.py | 11 +++++++++-- tests/utils/test_auth.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/hatch/publish/auth.py b/src/hatch/publish/auth.py index 79790a543..4d3afbece 100644 --- a/src/hatch/publish/auth.py +++ b/src/hatch/publish/auth.py @@ -1,5 +1,7 @@ from __future__ import annotations +import keyring + from hatch.utils.fs import Path @@ -44,8 +46,6 @@ def __get_password(self) -> str: if password is not None: return password - import keyring - password = keyring.get_password(self._repo, self.username) if password is not None: return password @@ -62,6 +62,7 @@ def __get_username(self) -> str: or self._repo_config.get('user') or self._read_pypirc() or self._read_previous_working_user_data() + or self._read_keyring() ) if username is not None: return username @@ -72,6 +73,12 @@ def __get_username(self) -> str: self.__username_was_read = True return self._app.prompt(f"Username for '{self._repo_config['url']}' [__token__]") or '__token__' + def _read_keyring(self) -> str | None: + creds = keyring.get_credential(self._repo, None) + if not creds: + return None + return creds.username + def _read_previous_working_user_data(self) -> str | None: if self._pwu_path.is_file(): contents = self._pwu_path.read_text() diff --git a/tests/utils/test_auth.py b/tests/utils/test_auth.py index 67e666033..9a9a254f2 100644 --- a/tests/utils/test_auth.py +++ b/tests/utils/test_auth.py @@ -1,3 +1,4 @@ +import hatch.publish.auth from hatch.publish.auth import AuthenticationCredentials from hatch.utils.fs import Path @@ -42,3 +43,30 @@ def test_pypirc(fs): ) assert credentials.username == 'guido' assert credentials.password == 'gat' + + +def test_keyring_credentials(monkeypatch): + class MockKeyring: + @staticmethod + def get_credential(*_): + class Credential: + username = 'gat' + + return Credential() + + @staticmethod + def get_password(*_): + return 'guido' + + monkeypatch.setattr(hatch.publish.auth, 'keyring', MockKeyring) + + credentials = AuthenticationCredentials( + app=None, + cache_dir=Path('/none'), + options={}, + repo='arbitrary', + repo_config={'url': 'https://kaashandel.nl/'}, + ) + + assert credentials.username == 'gat' + assert credentials.password == 'guido'