|  | 
| 6 | 6 | import pretend | 
| 7 | 7 | import pypi_attestations._impl as impl | 
| 8 | 8 | import pytest | 
|  | 9 | +import sigstore | 
| 9 | 10 | from sigstore.dsse import _DigestSet, _StatementBuilder, _Subject | 
| 10 | 11 | from sigstore.models import Bundle | 
| 11 | 12 | from sigstore.oidc import IdentityToken | 
| @@ -57,6 +58,67 @@ def test_sign_invalid_dist_filename(self, tmp_path: Path) -> None: | 
| 57 | 58 |         ): | 
| 58 | 59 |             impl.Attestation.sign(pretend.stub(), bad_dist) | 
| 59 | 60 | 
 | 
|  | 61 | +    def test_sign_raises_attestation_exception( | 
|  | 62 | +        self, id_token: IdentityToken, tmp_path: Path | 
|  | 63 | +    ) -> None: | 
|  | 64 | +        non_existing_file = tmp_path / "invalid-name.tar.gz" | 
|  | 65 | +        with pytest.raises(impl.AttestationError, match="No such file"): | 
|  | 66 | +            impl.Attestation.sign(pretend.stub(), non_existing_file) | 
|  | 67 | + | 
|  | 68 | +        bad_wheel_filename = tmp_path / "invalid-name.whl" | 
|  | 69 | +        bad_wheel_filename.write_bytes(b"junk") | 
|  | 70 | + | 
|  | 71 | +        with pytest.raises(impl.AttestationError, match="Invalid wheel filename"): | 
|  | 72 | +            impl.Attestation.sign(pretend.stub(), bad_wheel_filename) | 
|  | 73 | + | 
|  | 74 | +        bad_sdist_filename = tmp_path / "invalid_name.tar.gz" | 
|  | 75 | +        bad_sdist_filename.write_bytes(b"junk") | 
|  | 76 | + | 
|  | 77 | +        with pytest.raises(impl.AttestationError, match="Invalid sdist filename"): | 
|  | 78 | +            impl.Attestation.sign(pretend.stub(), bad_sdist_filename) | 
|  | 79 | + | 
|  | 80 | +    def test_wrong_predicate_raises_exception( | 
|  | 81 | +        self, id_token: IdentityToken, monkeypatch: pytest.MonkeyPatch | 
|  | 82 | +    ) -> None: | 
|  | 83 | +        def dummy_predicate(self_: _StatementBuilder, _: str) -> _StatementBuilder: | 
|  | 84 | +            # wrong type here to have a validation error | 
|  | 85 | +            self_._predicate_type = False | 
|  | 86 | +            return self_ | 
|  | 87 | + | 
|  | 88 | +        monkeypatch.setattr(sigstore.dsse._StatementBuilder, "predicate_type", dummy_predicate) | 
|  | 89 | +        with pytest.raises(impl.AttestationError, match="invalid statement"): | 
|  | 90 | +            impl.Attestation.sign(pretend.stub(), artifact_path) | 
|  | 91 | + | 
|  | 92 | +    def test_expired_certificate( | 
|  | 93 | +        self, id_token: IdentityToken, monkeypatch: pytest.MonkeyPatch | 
|  | 94 | +    ) -> None: | 
|  | 95 | +        def in_validity_period(_: IdentityToken) -> bool: | 
|  | 96 | +            return False | 
|  | 97 | + | 
|  | 98 | +        monkeypatch.setattr(IdentityToken, "in_validity_period", in_validity_period) | 
|  | 99 | + | 
|  | 100 | +        sign_ctx = SigningContext.staging() | 
|  | 101 | +        with sign_ctx.signer(id_token, cache=False) as signer: | 
|  | 102 | +            with pytest.raises(impl.AttestationError): | 
|  | 103 | +                impl.Attestation.sign(signer, artifact_path) | 
|  | 104 | + | 
|  | 105 | +    def test_multiple_signatures( | 
|  | 106 | +        self, id_token: IdentityToken, monkeypatch: pytest.MonkeyPatch | 
|  | 107 | +    ) -> None: | 
|  | 108 | +        def get_bundle(*_) -> Bundle:  # noqa: ANN002 | 
|  | 109 | +            # Duplicate the signature to trigger a Conversion error | 
|  | 110 | +            bundle = Bundle.from_json(gh_signed_bundle_path.read_bytes()) | 
|  | 111 | +            bundle._inner.dsse_envelope.signatures.append(bundle._inner.dsse_envelope.signatures[0]) | 
|  | 112 | +            return bundle | 
|  | 113 | + | 
|  | 114 | +        monkeypatch.setattr(sigstore.sign.Signer, "sign_dsse", get_bundle) | 
|  | 115 | + | 
|  | 116 | +        sign_ctx = SigningContext.staging() | 
|  | 117 | + | 
|  | 118 | +        with pytest.raises(impl.AttestationError): | 
|  | 119 | +            with sign_ctx.signer(id_token) as signer: | 
|  | 120 | +                impl.Attestation.sign(signer, artifact_path) | 
|  | 121 | + | 
| 60 | 122 |     def test_verify_github_attested(self) -> None: | 
| 61 | 123 |         verifier = Verifier.production() | 
| 62 | 124 |         pol = policy.AllOf( | 
|  | 
0 commit comments