from collections import defaultdict from contextlib import nullcontext as does_not_raise from copy import deepcopy from datetime import datetime from pathlib import Path from random import choice from string import digits from typing import ContextManager from typing import Dict from typing import List from typing import Optional from typing import Set from unittest.mock import Mock from unittest.mock import patch from pytest import mark from pytest import raises from libkeyringctl import keyring from libkeyringctl.keyring import PACKET_FILENAME_DATETIME_FORMAT from libkeyringctl.types import Fingerprint from libkeyringctl.types import TrustFilter from libkeyringctl.types import Uid from libkeyringctl.types import Username from .conftest import create_certificate from .conftest import create_key_revocation from .conftest import create_signature_revocation from .conftest import create_uid_certification from .conftest import test_all_fingerprints from .conftest import test_certificates from .conftest import test_keyring_certificates from .conftest import test_keys from .conftest import test_main_fingerprints def test_is_pgp_fingerprint( valid_fingerprint: str, invalid_fingerprint: str, ) -> None: assert keyring.is_pgp_fingerprint(string=valid_fingerprint) is True assert keyring.is_pgp_fingerprint(string=invalid_fingerprint) is False @mark.parametrize( "create_paths, create_paths_in_keyring_dir", [ (True, False), (True, True), (False, True), (False, False), ], ) def test_transform_username_to_keyring_path( create_paths: bool, create_paths_in_keyring_dir: bool, working_dir: Path, keyring_dir: Path, ) -> None: paths = [Path("test")] input_paths = deepcopy(paths) for index, path in enumerate(paths): path_in_working_dir = working_dir / path if create_paths: path_in_working_dir.mkdir() if create_paths_in_keyring_dir: (keyring_dir / path).mkdir(parents=True) paths[index] = path_in_working_dir modified_paths = deepcopy(paths) keyring.transform_username_to_keyring_path(keyring_dir=keyring_dir, paths=paths) for index, path in enumerate(paths): if create_paths or (not create_paths and not create_paths_in_keyring_dir): assert path == modified_paths[index] if not create_paths and create_paths_in_keyring_dir: assert path == keyring_dir / input_paths[index] @mark.parametrize( "fingerprint_path, create_paths, create_paths_in_keyring_dir", [ (True, True, False), (True, True, True), (True, False, True), (True, False, False), (False, True, False), (False, True, True), (False, False, True), (False, False, False), ], ) def test_transform_fingerprint_to_keyring_path( fingerprint_path: bool, create_paths: bool, create_paths_in_keyring_dir: bool, working_dir: Path, keyring_dir: Path, valid_fingerprint: str, ) -> None: paths = [Path(valid_fingerprint) if fingerprint_path else Path("test")] input_paths = deepcopy(paths) keyring_subdir = keyring_dir / "type" / "username" for index, path in enumerate(paths): path_in_working_dir = working_dir / path if create_paths: path_in_working_dir.mkdir() if create_paths_in_keyring_dir: (keyring_subdir / path).mkdir(parents=True) paths[index] = path_in_working_dir modified_paths = deepcopy(paths) keyring.transform_fingerprint_to_keyring_path(keyring_root=keyring_dir, paths=paths) for index, path in enumerate(paths): if create_paths or (not fingerprint_path and not create_paths): assert path == modified_paths[index] if not create_paths and fingerprint_path and create_paths_in_keyring_dir: assert path == keyring_subdir / input_paths[index] @mark.parametrize( "valid_current_packet_fingerprint, packet_type, issuer, expectation", [ (True, "KeyRevocation", "self", does_not_raise()), (True, "DirectKey", "self", does_not_raise()), (True, "GenericCertification", "self", does_not_raise()), (True, "KeyRevocation", None, does_not_raise()), (True, "CertificationRevocation", None, does_not_raise()), (True, "CertificationRevocation", "self", does_not_raise()), (True, "DirectKey", None, does_not_raise()), (True, "GenericCertification", None, does_not_raise()), (True, "KeyRevocation", "foo", raises(Exception)), (True, "DirectKey", "foo", does_not_raise()), (True, "GenericCertification", "foo", does_not_raise()), (True, "foo", "foo", does_not_raise()), (True, "foo", "self", raises(Exception)), (False, "KeyRevocation", True, raises(Exception)), (False, "DirectKey", True, raises(Exception)), (False, "GenericCertification", True, raises(Exception)), (False, "CertificationRevocation", True, raises(Exception)), ], ) @patch("libkeyringctl.keyring.get_fingerprint_from_partial") @patch("libkeyringctl.keyring.packet_dump_field") def test_convert_pubkey_signature_packet( packet_dump_field_mock: Mock, get_fingerprint_from_partial_mock: Mock, valid_current_packet_fingerprint: bool, packet_type: str, issuer: Optional[str], expectation: ContextManager[str], working_dir: Path, valid_fingerprint: Fingerprint, ) -> None: packet = working_dir / "packet" key_revocations: Dict[Fingerprint, Path] = {} direct_revocations: Dict[Fingerprint, List[Path]] = defaultdict(list) direct_sigs: Dict[Fingerprint, List[Path]] = defaultdict(list) current_packet_fingerprint = None if valid_current_packet_fingerprint: current_packet_fingerprint = valid_fingerprint packet_dump_field_mock.return_value = packet_type if issuer == "self": get_fingerprint_from_partial_mock.return_value = valid_fingerprint else: get_fingerprint_from_partial_mock.return_value = None if issuer is None else Fingerprint(issuer) with expectation: keyring.convert_pubkey_signature_packet( packet=packet, certificate_fingerprint=valid_fingerprint, fingerprint_filter=None, current_packet_fingerprint=current_packet_fingerprint, key_revocations=key_revocations, direct_revocations=direct_revocations, direct_sigs=direct_sigs, ) if issuer is None or current_packet_fingerprint is None: assert not direct_revocations and not direct_sigs and not key_revocations else: if packet_type == "KeyRevocation": assert key_revocations[valid_fingerprint] == packet elif packet_type in ["CertificationRevocation"]: if issuer != "self": assert not direct_revocations else: assert direct_revocations[valid_fingerprint if issuer == "self" else Fingerprint(issuer)] == [ packet ] elif packet_type in ["DirectKey", "GenericCertification"]: if issuer != "self": assert not direct_sigs else: assert direct_sigs[valid_fingerprint if issuer == "self" else Fingerprint(issuer)] == [packet] @mark.parametrize( "valid_current_packet_uid, packet_type, provide_issuer, issuer_in_filter, expectation", [ (True, "CertificationRevocation", "self", True, does_not_raise()), (True, "CertificationRevocation", "self", False, does_not_raise()), (True, "SomeCertification", "self", True, does_not_raise()), (True, "SomeCertification", "self", False, does_not_raise()), (True, "CertificationRevocation", None, True, does_not_raise()), (True, "CertificationRevocation", None, False, does_not_raise()), (True, "SomeCertification", None, True, does_not_raise()), (True, "SomeCertification", None, False, does_not_raise()), (False, "CertificationRevocation", "self", True, raises(Exception)), (False, "CertificationRevocation", "self", False, raises(Exception)), (False, "SomeCertification", "self", True, raises(Exception)), (False, "SomeCertification", "self", False, raises(Exception)), (True, "foo", "self", True, raises(Exception)), (True, "foo", "self", False, raises(Exception)), ], ) @patch("libkeyringctl.keyring.get_fingerprint_from_partial") @patch("libkeyringctl.keyring.packet_dump_field") def test_convert_uid_signature_packet( packet_dump_field_mock: Mock, get_fingerprint_from_partial_mock: Mock, valid_current_packet_uid: bool, packet_type: str, provide_issuer: Optional[str], issuer_in_filter: bool, expectation: ContextManager[str], working_dir: Path, valid_fingerprint: Fingerprint, ) -> None: packet = working_dir / "packet" certifications: Dict[Uid, Dict[Fingerprint, List[Path]]] = defaultdict(lambda: defaultdict(list)) revocations: Dict[Uid, Dict[Fingerprint, List[Path]]] = defaultdict(lambda: defaultdict(list)) current_packet_uid = None issuer = None fingerprint_filter: Set[Fingerprint] = {Fingerprint("foo")} if valid_current_packet_uid: current_packet_uid = Uid("Foobar McFooface ") packet_dump_field_mock.return_value = packet_type if provide_issuer == "self": issuer = valid_fingerprint else: if provide_issuer is not None: issuer = Fingerprint(provide_issuer) get_fingerprint_from_partial_mock.return_value = issuer if issuer_in_filter and issuer is not None: fingerprint_filter.add(issuer) with expectation: keyring.convert_uid_signature_packet( packet=packet, current_packet_uid=current_packet_uid, fingerprint_filter=fingerprint_filter, certifications=certifications, revocations=revocations, ) if not valid_current_packet_uid or issuer is None: assert not certifications and not revocations else: if packet_type == "CertificationRevocation" and valid_current_packet_uid and issuer_in_filter: assert revocations[current_packet_uid][issuer] == [packet] # type: ignore elif packet_type.endswith("Certification") and issuer_in_filter: assert certifications[current_packet_uid][issuer] == [packet] # type: ignore elif packet_type.endswith("Certification") and not issuer_in_filter: assert not certifications @mark.parametrize( "valid_current_packet_fingerprint, packet_type, issuer, expectation", [ (True, "SubkeyBinding", "self", does_not_raise()), (True, "SubkeyRevocation", "self", does_not_raise()), (True, "SubkeyBinding", None, does_not_raise()), (True, "SubkeyRevocation", None, does_not_raise()), (True, "SubkeyBinding", "foo", raises(Exception)), (True, "SubkeyRevocation", "foo", raises(Exception)), (False, "SubkeyBinding", "self", raises(Exception)), (False, "SubkeyRevocation", "self", raises(Exception)), (True, "foo", "self", raises(Exception)), ], ) @patch("libkeyringctl.keyring.get_fingerprint_from_partial") @patch("libkeyringctl.keyring.packet_dump_field") def test_convert_subkey_signature_packet( packet_dump_field_mock: Mock, get_fingerprint_from_partial_mock: Mock, valid_current_packet_fingerprint: bool, packet_type: str, issuer: Optional[str], expectation: ContextManager[str], working_dir: Path, valid_fingerprint: Fingerprint, ) -> None: packet = working_dir / "packet" subkey_bindings: Dict[Fingerprint, List[Path]] = defaultdict(list) subkey_revocations: Dict[Fingerprint, List[Path]] = defaultdict(list) current_packet_fingerprint = None if valid_current_packet_fingerprint: current_packet_fingerprint = valid_fingerprint packet_dump_field_mock.return_value = packet_type if issuer == "self": get_fingerprint_from_partial_mock.return_value = valid_fingerprint else: get_fingerprint_from_partial_mock.return_value = None if issuer is None else Fingerprint(issuer) with expectation: keyring.convert_subkey_signature_packet( packet=packet, certificate_fingerprint=valid_fingerprint, current_packet_fingerprint=current_packet_fingerprint, fingerprint_filter=None, subkey_bindings=subkey_bindings, subkey_revocations=subkey_revocations, ) if issuer is None or not valid_current_packet_fingerprint: assert not subkey_bindings and not subkey_revocations else: if packet_type == "SubkeyBinding" and issuer == "self": assert subkey_bindings[valid_fingerprint] == [packet] elif packet_type == "SubkeyRevocation" and issuer == "self": assert subkey_revocations[valid_fingerprint] == [packet] @mark.parametrize( "valid_certificate_fingerprint, current_packet_mode, expectation", [ (True, "pubkey", does_not_raise()), (True, "uid", does_not_raise()), (True, "subkey", does_not_raise()), (True, "uattr", does_not_raise()), (False, "pubkey", raises(Exception)), (False, "uid", raises(Exception)), (False, "subkey", raises(Exception)), (False, "uattr", raises(Exception)), (True, "foo", raises(Exception)), ], ) @patch("libkeyringctl.keyring.convert_pubkey_signature_packet") @patch("libkeyringctl.keyring.convert_uid_signature_packet") @patch("libkeyringctl.keyring.convert_subkey_signature_packet") def test_convert_signature_packet( convert_subkey_signature_packet_mock: Mock, convert_uid_signature_packet_mock: Mock, convert_pubkey_signature_packet_mock: Mock, valid_certificate_fingerprint: bool, current_packet_mode: str, expectation: ContextManager[str], valid_fingerprint: Fingerprint, ) -> None: certificate_fingerprint = None key_revocations: Dict[Fingerprint, Path] = {} direct_revocations: Dict[Fingerprint, List[Path]] = defaultdict(list) direct_sigs: Dict[Fingerprint, List[Path]] = defaultdict(list) certifications: Dict[Uid, Dict[Fingerprint, List[Path]]] = defaultdict(lambda: defaultdict(list)) revocations: Dict[Uid, Dict[Fingerprint, List[Path]]] = defaultdict(lambda: defaultdict(list)) subkey_bindings: Dict[Fingerprint, List[Path]] = defaultdict(list) subkey_revocations: Dict[Fingerprint, List[Path]] = defaultdict(list) if valid_certificate_fingerprint: certificate_fingerprint = valid_fingerprint with expectation: keyring.convert_signature_packet( packet=Path("foo"), current_packet_mode=current_packet_mode, certificate_fingerprint=certificate_fingerprint, fingerprint_filter=None, key_revocations=key_revocations, current_packet_fingerprint=None, current_packet_uid=None, direct_revocations=direct_revocations, direct_sigs=direct_sigs, certifications=certifications, revocations=revocations, subkey_bindings=subkey_bindings, subkey_revocations=subkey_revocations, ) if current_packet_mode == "pubkey": convert_pubkey_signature_packet_mock.assert_called_once() elif current_packet_mode == "uid": convert_uid_signature_packet_mock.assert_called_once() elif current_packet_mode == "subkey": convert_subkey_signature_packet_mock.assert_called_once() @mark.parametrize( "packet, packet_split, packet_dump_field, name_override, expectation", [ ( Path("foo.asc"), [ Path("--PublicKey"), Path("--Signature"), Path("--UserID"), Path("--UserAttribute"), Path("--PublicSubkey"), Path("--Signature"), ], [ "".join(choice("ABCDEF" + digits) for _ in range(40)), "foo ", "".join(choice("ABCDEF" + digits) for _ in range(40)), ], "bar", does_not_raise(), ), ( Path("foo.asc"), [ Path("--PublicKey"), Path("--Signature"), Path("--UserID"), Path("--UserID"), ], [ "".join(choice("ABCDEF" + digits) for _ in range(40)), "foo ", "foo ", ], "bar", raises(Exception), ), ( Path("foo.asc"), [ Path("--SecretKey"), ], [], None, raises(Exception), ), ( Path("foo.asc"), [ Path("foo"), ], [], None, raises(Exception), ), ( Path("foo.asc"), [ Path("--PublicKey"), ], [ None, ], "bar", raises(Exception), ), ], ) @patch("libkeyringctl.keyring.persist_key_material") @patch("libkeyringctl.keyring.packet_split") @patch("libkeyringctl.keyring.convert_signature_packet") @patch("libkeyringctl.keyring.packet_dump_field") @patch("libkeyringctl.keyring.derive_username_from_fingerprint") def test_convert_certificate( derive_username_from_fingerprint_mock: Mock, packet_dump_field_mock: Mock, convert_signature_packet_mock: Mock, packet_split_mock: Mock, persist_key_material_mock: Mock, packet: Path, packet_split: List[Path], packet_dump_field: List[str], name_override: Optional[Username], expectation: ContextManager[str], working_dir: Path, keyring_dir: Path, ) -> None: packet_split_mock.return_value = packet_split packet_dump_field_mock.side_effect = packet_dump_field with expectation: keyring.convert_certificate( working_dir=working_dir, certificate=packet, keyring_dir=keyring_dir, name_override=name_override, fingerprint_filter=None, ) @patch("libkeyringctl.keyring.latest_certification") @patch("libkeyringctl.keyring.packet_join") def test_persist_subkey_revocations( packet_join_mock: Mock, latest_certification_mock: Mock, working_dir: Path, keyring_dir: Path, valid_fingerprint: Fingerprint, ) -> None: revocation_packet = working_dir / "latest_revocation.asc" latest_certification_mock.return_value = revocation_packet subkey_revocations: Dict[Fingerprint, List[Path]] = { valid_fingerprint: [revocation_packet, working_dir / "earlier_revocation.asc"] } keyring.persist_subkey_revocations( key_dir=keyring_dir, subkey_revocations=subkey_revocations, issuer=valid_fingerprint, ) packet_join_mock.assert_called_once_with( packets=[revocation_packet], output=keyring_dir / "subkey" / valid_fingerprint / "revocation" / f"{valid_fingerprint}.asc", force=True, ) @patch("libkeyringctl.keyring.packet_signature_creation_time") @patch("libkeyringctl.keyring.packet_join") def test_persist_directkey_revocations( packet_join_mock: Mock, packet_signature_creation_time_mock: Mock, working_dir: Path, keyring_dir: Path, valid_fingerprint: Fingerprint, ) -> None: revocation_packet = working_dir / "latest_revocation.asc" directkey_revocations: Dict[Fingerprint, List[Path]] = {valid_fingerprint: [revocation_packet]} dt = datetime(2000, 1, 12, 11, 22, 33) packet_signature_creation_time_mock.return_value = dt keyring.persist_direct_key_revocations( key_dir=keyring_dir, direct_key_revocations=directkey_revocations, ) packet_join_mock.assert_called_once_with( packets=[revocation_packet], output=keyring_dir / "directkey" / "revocation" / valid_fingerprint / f"{dt.strftime(PACKET_FILENAME_DATETIME_FORMAT)}.asc", force=True, ) @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) def test_convert(working_dir: Path, keyring_dir: Path) -> None: keyring.convert( working_dir=working_dir, keyring_root=keyring_dir, sources=test_certificates[Username("foobar")], target_dir=keyring_dir / "packager", ) with raises(Exception): keyring.convert( working_dir=working_dir, keyring_root=keyring_dir, sources=test_keys[Username("foobar")], target_dir=keyring_dir / "packager", ) @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) @create_uid_certification(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar ")) @create_signature_revocation(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar ")) def test_clean_keyring(working_dir: Path, keyring_dir: Path) -> None: # first pass clean up certification keyring.clean_keyring(keyring=keyring_dir) # second pass skipping clean up because lack of certification keyring.clean_keyring(keyring=keyring_dir) @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("other_main"), uids=[Uid("other main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) def test_export_ownertrust(working_dir: Path, keyring_dir: Path) -> None: output = working_dir / "build" keyring.export_ownertrust( certs=[keyring_dir / "main"], keyring_root=keyring_dir, output=output, ) with open(file=output, mode="r") as output_file: for line in output_file.readlines(): assert line.split(":")[0] in test_main_fingerprints @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) @create_key_revocation(username=Username("foobar")) def test_export_revoked(working_dir: Path, keyring_dir: Path) -> None: output = working_dir / "build" keyring.export_revoked( certs=[keyring_dir / "packager"], keyring_root=keyring_dir, main_keys=test_main_fingerprints, output=output, ) revoked_fingerprints = test_all_fingerprints - test_main_fingerprints with open(file=output, mode="r") as output_file: for line in output_file.readlines(): assert line.strip() in revoked_fingerprints @mark.parametrize("path_exists", [(True), (False)]) @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) @create_uid_certification(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar ")) @create_key_revocation(username=Username("foobar")) def test_get_packets_from_path(working_dir: Path, keyring_dir: Path, path_exists: bool) -> None: if not path_exists: assert keyring.get_packets_from_path(path=working_dir / "nope") == [] else: for username, paths in test_keyring_certificates.items(): for path in paths: keyring.get_packets_from_path(path=path) @mark.parametrize("path_exists", [(True), (False)]) @patch("libkeyringctl.keyring.get_packets_from_path") def test_get_packets_from_listing(get_packets_from_path_mock: Mock, working_dir: Path, path_exists: bool) -> None: path = working_dir / "path" if not path_exists: assert keyring.get_packets_from_listing(path=path) == [] else: get_packets_from_path_mock.return_value = [] sub_path = path / "sub" sub_path.mkdir(parents=True) assert keyring.get_packets_from_listing(path=path) == [] get_packets_from_path_mock.assert_called_once_with(sub_path) @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) @create_uid_certification(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar ")) @create_key_revocation(username=Username("foobar")) def test_export(working_dir: Path, keyring_dir: Path) -> None: output_file = working_dir / "output" empty_dir = working_dir / "empty" empty_dir.mkdir() assert not keyring.export(working_dir=working_dir, keyring_root=empty_dir, sources=None, output=output_file) assert not output_file.exists() keyring.export(working_dir=working_dir, keyring_root=keyring_dir, sources=None, output=output_file) assert output_file.exists() @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) @create_uid_certification(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar ")) @create_key_revocation(username=Username("foobar")) def test_build(working_dir: Path, keyring_dir: Path) -> None: output_dir = working_dir / "output" with raises(FileNotFoundError): empty_dir = working_dir / "empty" empty_dir.mkdir() keyring.build(working_dir=working_dir, keyring_root=empty_dir, target_dir=output_dir) keyring.build(working_dir=working_dir, keyring_root=keyring_dir, target_dir=output_dir) assert ( (output_dir / "archlinux.gpg").exists() and (output_dir / "archlinux-trusted").exists() and (output_dir / "archlinux-revoked").exists() ) @mark.parametrize( "create_dir, duplicate_fingerprints, expectation", [ (True, False, does_not_raise()), (True, True, raises(Exception)), (False, False, does_not_raise()), (False, True, does_not_raise()), ], ) def test_derive_username_from_fingerprint( create_dir: bool, duplicate_fingerprints: bool, expectation: ContextManager[str], keyring_dir: Path, valid_fingerprint: str, ) -> None: username = "username" other_username = "other_user" typed_keyring_dir = keyring_dir / "type" if create_dir: (typed_keyring_dir / username / valid_fingerprint).mkdir(parents=True) if duplicate_fingerprints: (typed_keyring_dir / other_username / valid_fingerprint).mkdir(parents=True) with expectation: returned_username = keyring.derive_username_from_fingerprint( keyring_dir=typed_keyring_dir, certificate_fingerprint=Fingerprint(valid_fingerprint), ) if create_dir and not duplicate_fingerprints: assert returned_username == username else: assert returned_username is None @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) def test_list_keyring(working_dir: Path, keyring_dir: Path) -> None: packager_fingerprints = test_all_fingerprints - test_main_fingerprints with patch("builtins.print") as print_mock: keyring.list_keyring(keyring_root=keyring_dir, sources=None, main_keys=False) print_args = [mock_call[1][0] for mock_call in print_mock.mock_calls] for fingerprint in packager_fingerprints: assert any([fingerprint in print_arg for print_arg in print_args]) with patch("builtins.print") as print_mock: keyring.list_keyring(keyring_root=keyring_dir, sources=None, main_keys=True) print_args = [mock_call[1][0] for mock_call in print_mock.mock_calls] for fingerprint in test_main_fingerprints: assert any([fingerprint in print_arg for print_arg in print_args]) for name, paths in test_keyring_certificates.items(): if all(["main" in str(path) for path in paths]): for path in paths: with patch("builtins.print") as print_mock: keyring.list_keyring(keyring_root=keyring_dir, sources=[path], main_keys=True) print_args = [mock_call[1][0] for mock_call in print_mock.mock_calls] assert name in print_args[0] and path.stem in print_args[0] elif all(["packager" in str(path) for path in paths]): for path in paths: with patch("builtins.print") as print_mock: keyring.list_keyring(keyring_root=keyring_dir, sources=[path], main_keys=False) print_args = [mock_call[1][0] for mock_call in print_mock.mock_calls] assert name in print_args[0] and path.stem in print_args[0] with patch("builtins.print") as print_mock: keyring.list_keyring( keyring_root=keyring_dir, sources=paths, main_keys=False, trust_filter=TrustFilter.revoked ) print_args = [mock_call[1][0] for mock_call in print_mock.mock_calls] assert not print_args @create_certificate(username=Username("main"), uids=[Uid("main ")], keyring_type="main") @create_certificate(username=Username("foobar"), uids=[Uid("foobar ")]) def test_inspect_keyring(working_dir: Path, keyring_dir: Path) -> None: inspect_string = keyring.inspect_keyring(working_dir=working_dir, keyring_root=keyring_dir, sources=None) for fingerprint in test_all_fingerprints: assert fingerprint in inspect_string for name, paths in test_keyring_certificates.items(): if all(["main" in str(path) for path in paths]): for path in paths: inspect_string = keyring.inspect_keyring( working_dir=working_dir, keyring_root=keyring_dir, sources=[path], ) assert path.stem in inspect_string elif all(["packager" in str(path) for path in paths]): for path in paths: inspect_string = keyring.inspect_keyring( working_dir=working_dir, keyring_root=keyring_dir, sources=[path], ) assert path.stem in inspect_string def test_get_fingerprints_from_paths(keyring_dir: Path, valid_fingerprint: str, valid_subkey_fingerprint: str) -> None: fingerprint_dir = keyring_dir / "type" / "username" / valid_fingerprint fingerprint_dir.mkdir(parents=True) (fingerprint_dir / (fingerprint_dir.name + ".asc")).touch() fingerprint_subkey_dir = fingerprint_dir / "subkey" / valid_subkey_fingerprint fingerprint_subkey_dir.mkdir(parents=True) fingerprint_subkey_asc = fingerprint_subkey_dir / (fingerprint_subkey_dir.name + ".asc") fingerprint_subkey_asc.touch() assert keyring.get_fingerprints_from_paths(sources=[fingerprint_subkey_dir]) == { Fingerprint(valid_subkey_fingerprint) } assert keyring.get_fingerprints_from_paths(sources=[fingerprint_dir]) == {Fingerprint(valid_fingerprint)}