1212import requests
1313import sigstore .oidc
1414from pretend import raiser , stub
15- from sigstore .oidc import IdentityError
15+ from sigstore .oidc import IdentityError , IdentityToken
1616
1717import pypi_attestations ._cli
1818from pypi_attestations ._cli import (
2424from pypi_attestations ._impl import Attestation , AttestationError , ConversionError , Distribution
2525
2626ONLINE_TESTS = (
27- "CI" in os .environ or "TEST_INTERACTIVE " in os .environ
27+ "CI" in os .environ or "EXTREMELY_DANGEROUS_PUBLIC_OIDC_BEACON " in os .environ
2828) and "TEST_OFFLINE" not in os .environ
2929
3030online = pytest .mark .skipif (not ONLINE_TESTS , reason = "online tests not enabled" )
@@ -75,7 +75,9 @@ def default_sign(_: argparse.Namespace) -> None:
7575
7676
7777@online
78- def test_get_identity_token (monkeypatch : pytest .MonkeyPatch ) -> None :
78+ def test_get_identity_token (id_token : IdentityToken , monkeypatch : pytest .MonkeyPatch ) -> None :
79+ monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : id_token ._raw_token )
80+
7981 # Happy paths
8082 identity_token = get_identity_token (argparse .Namespace (staging = True ))
8183 assert identity_token .in_validity_period ()
@@ -92,7 +94,11 @@ def return_invalid_token() -> str:
9294
9395
9496@online
95- def test_sign_command (tmp_path : Path ) -> None :
97+ def test_sign_command (
98+ id_token : IdentityToken , tmp_path : Path , monkeypatch : pytest .MonkeyPatch
99+ ) -> None :
100+ monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : id_token ._raw_token )
101+
96102 # Happy path
97103 copied_artifact = tmp_path / artifact_path .name
98104 shutil .copy (artifact_path , copied_artifact )
@@ -112,7 +118,11 @@ def test_sign_command(tmp_path: Path) -> None:
112118
113119
114120@online
115- def test_sign_missing_file (caplog : pytest .LogCaptureFixture ) -> None :
121+ def test_sign_missing_file (
122+ id_token : IdentityToken , caplog : pytest .LogCaptureFixture , monkeypatch : pytest .MonkeyPatch
123+ ) -> None :
124+ monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : id_token ._raw_token )
125+
116126 # Missing file
117127 with pytest .raises (SystemExit ):
118128 run_main_with_command (
@@ -127,7 +137,14 @@ def test_sign_missing_file(caplog: pytest.LogCaptureFixture) -> None:
127137
128138
129139@online
130- def test_sign_signature_already_exists (tmp_path : Path , caplog : pytest .LogCaptureFixture ) -> None :
140+ def test_sign_signature_already_exists (
141+ id_token : IdentityToken ,
142+ tmp_path : Path ,
143+ caplog : pytest .LogCaptureFixture ,
144+ monkeypatch : pytest .MonkeyPatch ,
145+ ) -> None :
146+ monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : id_token ._raw_token )
147+
131148 artifact = tmp_path / artifact_path .with_suffix (".copy2.whl" ).name
132149 artifact .touch (exist_ok = False )
133150
@@ -168,7 +185,14 @@ def return_invalid_token() -> str:
168185
169186
170187@online
171- def test_sign_invalid_artifact (caplog : pytest .LogCaptureFixture , tmp_path : Path ) -> None :
188+ def test_sign_invalid_artifact (
189+ id_token : IdentityToken ,
190+ caplog : pytest .LogCaptureFixture ,
191+ tmp_path : Path ,
192+ monkeypatch : pytest .MonkeyPatch ,
193+ ) -> None :
194+ monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : id_token ._raw_token )
195+
172196 artifact = tmp_path / "pkg-1.0.0.exe"
173197 artifact .touch (exist_ok = False )
174198
@@ -180,8 +204,12 @@ def test_sign_invalid_artifact(caplog: pytest.LogCaptureFixture, tmp_path: Path)
180204
181205@online
182206def test_sign_fail_to_sign (
183- monkeypatch : pytest .MonkeyPatch , caplog : pytest .LogCaptureFixture , tmp_path : Path
207+ id_token : IdentityToken ,
208+ monkeypatch : pytest .MonkeyPatch ,
209+ caplog : pytest .LogCaptureFixture ,
210+ tmp_path : Path ,
184211) -> None :
212+ monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : id_token ._raw_token )
185213 monkeypatch .setattr (pypi_attestations ._cli , "Attestation" , stub (sign = raiser (AttestationError )))
186214 copied_artifact = tmp_path / artifact_path .name
187215 shutil .copy (artifact_path , copied_artifact )
@@ -245,10 +273,7 @@ def test_verify_attestation_command(caplog: pytest.LogCaptureFixture) -> None:
245273 artifact_path .as_posix (),
246274 ]
247275 )
248- assert (
249- "Verification failed: failed to build chain: unable to get local issuer certificate"
250- in caplog .text
251- )
276+ assert "Verification failed: failed to build timestamp certificate chain" in caplog .text
252277 assert "OK:" not in caplog .text
253278
254279
@@ -329,19 +354,23 @@ def test_verify_attestation_invalid_artifact(
329354 assert "Invalid Python package distribution" in caplog .text
330355
331356
332- def test_get_identity_token_oauth_flow (monkeypatch : pytest .MonkeyPatch ) -> None :
357+ @online
358+ @pytest .mark .parametrize ("staging" , [True , False ])
359+ def test_get_identity_token_oauth_flow (staging : bool , monkeypatch : pytest .MonkeyPatch ) -> None :
333360 # If no ambient credential is available, default to the OAuth2 flow
334361 monkeypatch .setattr (sigstore .oidc , "detect_credential" , lambda : None )
335362 identity_token = stub ()
336363
337364 class MockIssuer :
338- @staticmethod
339- def staging () -> stub :
340- return stub (identity_token = lambda : identity_token )
365+ def __init__ (self , * args : object , ** kwargs : object ) -> None :
366+ pass
367+
368+ def identity_token (self ) -> sigstore .oidc .IdentityToken :
369+ return identity_token # type: ignore
341370
342371 monkeypatch .setattr (pypi_attestations ._cli , "Issuer" , MockIssuer )
343372
344- assert pypi_attestations ._cli .get_identity_token (stub (staging = True )) == identity_token
373+ assert pypi_attestations ._cli .get_identity_token (stub (staging = staging )) == identity_token
345374
346375
347376def test_validate_files (tmp_path : Path , caplog : pytest .LogCaptureFixture ) -> None :
@@ -463,10 +492,7 @@ def test_verify_pypi_command_env_fail(caplog: pytest.LogCaptureFixture) -> None:
463492 pypi_wheel_url ,
464493 ]
465494 )
466- assert (
467- "Verification failed: failed to build chain: unable to get local issuer certificate"
468- in caplog .text
469- )
495+ assert "Verification failed: failed to build timestamp certificate chain" in caplog .text
470496 assert "OK:" not in caplog .text
471497
472498
0 commit comments