mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-05-01 19:22:23 +02:00
(WIP) some more tests
This commit is contained in:
parent
651d988a37
commit
26638a5f2a
3 changed files with 80 additions and 8 deletions
|
@ -424,8 +424,7 @@ def get_remote_signatures(image: str, digest: str) -> List[Dict]:
|
||||||
|
|
||||||
# Remove the last return, split on newlines, convert from JSON
|
# Remove the last return, split on newlines, convert from JSON
|
||||||
signatures_raw = process.stdout.decode("utf-8").strip().split("\n")
|
signatures_raw = process.stdout.decode("utf-8").strip().split("\n")
|
||||||
signatures = list(map(json.loads, signatures_raw))
|
signatures = list(filter(bool, map(json.loads, signatures_raw)))
|
||||||
breakpoint()
|
|
||||||
if len(signatures) < 1:
|
if len(signatures) < 1:
|
||||||
raise errors.NoRemoteSignatures("No signatures found for the image")
|
raise errors.NoRemoteSignatures("No signatures found for the image")
|
||||||
return signatures
|
return signatures
|
||||||
|
|
|
@ -13,6 +13,13 @@ from dangerzone.gui import Application
|
||||||
sys.dangerzone_dev = True # type: ignore[attr-defined]
|
sys.dangerzone_dev = True # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
|
||||||
|
ASSETS_PATH = Path(__file__).parent / "assets"
|
||||||
|
TEST_PUBKEY_PATH = ASSETS_PATH / "test.pub.key"
|
||||||
|
INVALID_SIGNATURES_PATH = ASSETS_PATH / "signatures" / "invalid"
|
||||||
|
VALID_SIGNATURES_PATH = ASSETS_PATH / "signatures" / "valid"
|
||||||
|
TEMPERED_SIGNATURES_PATH = ASSETS_PATH / "signatures" / "tempered"
|
||||||
|
|
||||||
|
|
||||||
# Use this fixture to make `pytest-qt` invoke our custom QApplication.
|
# Use this fixture to make `pytest-qt` invoke our custom QApplication.
|
||||||
# See https://pytest-qt.readthedocs.io/en/latest/qapplication.html#testing-custom-qapplications
|
# See https://pytest-qt.readthedocs.io/en/latest/qapplication.html#testing-custom-qapplications
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
|
@ -133,6 +140,11 @@ for_each_doc = pytest.mark.parametrize(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def signature():
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
# External Docs - base64 docs encoded for externally sourced documents
|
# External Docs - base64 docs encoded for externally sourced documents
|
||||||
# XXX to reduce the chance of accidentally opening them
|
# XXX to reduce the chance of accidentally opening them
|
||||||
test_docs_external_dir = Path(__file__).parent.joinpath(SAMPLE_EXTERNAL_DIRECTORY)
|
test_docs_external_dir = Path(__file__).parent.joinpath(SAMPLE_EXTERNAL_DIRECTORY)
|
||||||
|
|
|
@ -32,6 +32,29 @@ TEMPERED_SIGNATURES_PATH = ASSETS_PATH / "signatures" / "tempered"
|
||||||
RANDOM_DIGEST = "aacc9b586648bbe3040f2822153b1d5ead2779af45ff750fd6f04daf4a9f64b4"
|
RANDOM_DIGEST = "aacc9b586648bbe3040f2822153b1d5ead2779af45ff750fd6f04daf4a9f64b4"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def valid_signature():
|
||||||
|
signature_file = next(VALID_SIGNATURES_PATH.glob("**/*.json"))
|
||||||
|
with open(signature_file, "r") as signature_file:
|
||||||
|
signatures = json.load(signature_file)
|
||||||
|
return signatures.pop()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def tempered_signature():
|
||||||
|
signature_file = next(TEMPERED_SIGNATURES_PATH.glob("**/*.json"))
|
||||||
|
with open(signature_file, "r") as signature_file:
|
||||||
|
signatures = json.load(signature_file)
|
||||||
|
return signatures.pop()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def signature_other_digest(valid_signature):
|
||||||
|
signature = valid_signature.copy()
|
||||||
|
signature["Bundle"]["Payload"]["digest"] = "sha256:123456"
|
||||||
|
return signature
|
||||||
|
|
||||||
|
|
||||||
def test_load_valid_signatures(mocker):
|
def test_load_valid_signatures(mocker):
|
||||||
mocker.patch("dangerzone.updater.signatures.SIGNATURES_PATH", VALID_SIGNATURES_PATH)
|
mocker.patch("dangerzone.updater.signatures.SIGNATURES_PATH", VALID_SIGNATURES_PATH)
|
||||||
valid_signatures = list(VALID_SIGNATURES_PATH.glob("**/*.json"))
|
valid_signatures = list(VALID_SIGNATURES_PATH.glob("**/*.json"))
|
||||||
|
@ -167,21 +190,30 @@ def test_get_remote_signatures_empty(fp: FakeProcess, mocker):
|
||||||
mocker.patch("dangerzone.updater.cosign.ensure_installed", return_value=True)
|
mocker.patch("dangerzone.updater.cosign.ensure_installed", return_value=True)
|
||||||
fp.register_subprocess(
|
fp.register_subprocess(
|
||||||
["cosign", "download", "signature", f"{image}@sha256:{digest}"],
|
["cosign", "download", "signature", f"{image}@sha256:{digest}"],
|
||||||
stdout=json.dumps([]),
|
stdout=json.dumps({}),
|
||||||
)
|
)
|
||||||
with pytest.raises(errors.NoRemoteSignatures):
|
with pytest.raises(errors.NoRemoteSignatures):
|
||||||
get_remote_signatures(image, digest)
|
get_remote_signatures(image, digest)
|
||||||
|
|
||||||
|
|
||||||
def test_get_remote_signatures_cosign_error():
|
def test_get_remote_signatures_cosign_error(mocker, fp: FakeProcess):
|
||||||
pass
|
image = "ghcr.io/freedomofpress/dangerzone/dangerzone"
|
||||||
|
digest = "123456"
|
||||||
|
mocker.patch("dangerzone.updater.cosign.ensure_installed", return_value=True)
|
||||||
|
fp.register_subprocess(
|
||||||
|
["cosign", "download", "signature", f"{image}@sha256:{digest}"],
|
||||||
|
returncode=1,
|
||||||
|
stderr="Error: no signatures associated",
|
||||||
|
)
|
||||||
|
with pytest.raises(errors.NoRemoteSignatures):
|
||||||
|
get_remote_signatures(image, digest)
|
||||||
|
|
||||||
|
|
||||||
def test_store_signatures_with_different_digests(
|
def test_store_signatures_with_different_digests(
|
||||||
valid_signature, signature_other_digest, mocker, tmp_path
|
valid_signature, signature_other_digest, mocker, tmp_path
|
||||||
):
|
):
|
||||||
"""Test that store_signatures raises an error when a signature's digest doesn't match."""
|
"""Test that store_signatures raises an error when a signature's digest doesn't match."""
|
||||||
|
signatures = [valid_signature, signature_other_digest]
|
||||||
image_digest = "sha256:123456"
|
image_digest = "sha256:123456"
|
||||||
|
|
||||||
# Mock the signatures path
|
# Mock the signatures path
|
||||||
|
@ -238,6 +270,34 @@ def test_stores_signatures_updates_last_log_index(valid_signature, mocker, tmp_p
|
||||||
signatures = [valid_signature]
|
signatures = [valid_signature]
|
||||||
# Extract the digest from the signature
|
# Extract the digest from the signature
|
||||||
image_digest = Signature(valid_signature).manifest_digest
|
image_digest = Signature(valid_signature).manifest_digest
|
||||||
|
signatures = [valid_signature, signature_other_digest]
|
||||||
|
breakpoint()
|
||||||
|
valid_signature, signature_other_digest, mocker, tmp_path
|
||||||
|
|
||||||
|
"""Test that store_signatures raises an error when a signature's digest doesn't match."""
|
||||||
|
|
||||||
|
image_digest = "sha256:123456"
|
||||||
|
|
||||||
|
# Mock the signatures path
|
||||||
|
signatures_path = tmp_path / "signatures"
|
||||||
|
signatures_path.mkdir()
|
||||||
|
mocker.patch("dangerzone.updater.signatures.SIGNATURES_PATH", signatures_path)
|
||||||
|
|
||||||
|
# Mock get_log_index_from_signatures
|
||||||
|
mocker.patch(
|
||||||
|
"dangerzone.updater.signatures.get_log_index_from_signatures",
|
||||||
|
return_value=100,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Mock get_last_log_index
|
||||||
|
mocker.patch(
|
||||||
|
"dangerzone.updater.signatures.get_last_log_index",
|
||||||
|
return_value=50,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_stores_signatures_updates_last_log_index():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_get_file_digest():
|
def test_get_file_digest():
|
||||||
|
@ -310,5 +370,6 @@ def test_verify_signature_tempered(tempered_signature):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_verify_signatures_not_0():
|
def test_verify_signatures_empty_list():
|
||||||
pass
|
with pytest.raises(errors.SignatureVerificationError):
|
||||||
|
verify_signatures([], "1234", TEST_PUBKEY_PATH)
|
||||||
|
|
Loading…
Reference in a new issue