Skip to content

Commit

Permalink
Test locked keyring
Browse files Browse the repository at this point in the history
* tests/conftest.py : Implement `LockedBackend` inheriting `KeyringBackend` and throwing `KeyringLocked` on access.

* tests\utils\test_authenticator.py : Test that locked keyrings still lead to a request.

* tests\utils\test_password_manager.py : Test that locked keyrings do not fail.
  • Loading branch information
real-yfprojects committed Aug 13, 2023
1 parent a66935a commit d507f5a
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
33 changes: 33 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,32 @@ def delete_password(self, service: str, username: str | None) -> None:
del self._passwords[service][username]


class LockedBackend(KeyringBackend):
@classmethod
def priority(cls) -> int:
return 42

def set_password(self, service: str, username: str | None, password: Any) -> None:
from keyring.errors import KeyringLocked

raise KeyringLocked()

def get_password(self, service: str, username: str | None) -> Any:
from keyring.errors import KeyringLocked

raise KeyringLocked()

def get_credential(self, service: str, username: str | None) -> Any:
from keyring.errors import KeyringLocked

raise KeyringLocked()

def delete_password(self, service: str, username: str | None) -> None:
from keyring.errors import KeyringLocked

raise KeyringLocked()


@pytest.fixture()
def dummy_keyring() -> DummyBackend:
return DummyBackend()
Expand All @@ -134,6 +160,13 @@ def with_fail_keyring() -> None:
keyring.set_keyring(Keyring()) # type: ignore[no-untyped-call]


@pytest.fixture()
def with_locked_keyring() -> None:
import keyring

keyring.set_keyring(LockedBackend()) # type: ignore[no-untyped-call]


@pytest.fixture()
def with_null_keyring() -> None:
import keyring
Expand Down
13 changes: 13 additions & 0 deletions tests/utils/test_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ def test_authenticator_uses_username_only_credentials(
assert request.headers["Authorization"] == "Basic Zm9vMDAxOg=="


def test_authenticator_ignores_locked_keyring(
mock_config: Config,
mock_remote: None,
http: type[httpretty.httpretty],
with_locked_keyring: None,
) -> None:
authenticator = Authenticator(mock_config, NullIO())
authenticator.request("get", "https://foo001@foo.bar/files/foo-0.1.0.tar.gz")
request = http.last_request()

assert request.headers["Authorization"] == "Basic Zm9vMDAxOg=="


def test_authenticator_uses_password_only_credentials(
mock_config: Config, mock_remote: None, http: type[httpretty.httpretty]
) -> None:
Expand Down
13 changes: 13 additions & 0 deletions tests/utils/test_password_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ def test_keyring_raises_errors_on_keyring_errors(
key_ring.delete_password("foo", "bar")


def test_keyring_returns_none_on_locked_keyring(with_locked_keyring: None) -> None:
key_ring = PoetryKeyring("poetry")

cred = key_ring.get_credential("any password", "any name")
assert cred.password is None


def test_keyring_with_chainer_backend_and_fail_keyring_should_be_unavailable(
with_chained_fail_keyring: None,
) -> None:
Expand Down Expand Up @@ -222,6 +229,12 @@ def test_fail_keyring_should_be_unavailable(
assert not key_ring.is_available()


def test_locked_keyring_should_be_available(with_locked_keyring: None) -> None:
key_ring = PoetryKeyring("poetry")

assert key_ring.is_available()


def test_get_http_auth_from_environment_variables(
environ: None, config: Config
) -> None:
Expand Down

0 comments on commit d507f5a

Please sign in to comment.