Skip to content

Commit 19d4e21

Browse files
committed
Verify also URLs of existing releases
1 parent 892a932 commit 19d4e21

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

tests/unit/forklift/test_legacy.py

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,11 +3815,11 @@ def failing_verify(_self, _verifier, _policy, _dist):
38153815
("https://google.com", False), # Totally different
38163816
("https://github.com/foo", False), # Missing parts
38173817
("https://github.com/foo/bar/", True), # Exactly the same
3818-
("https://github.com/foo/bar/readme.md", True), # Additonal parts
3818+
("https://github.com/foo/bar/readme.md", True), # Additional parts
38193819
("https://github.com/foo/bar", True), # Missing trailing slash
38203820
],
38213821
)
3822-
def test_release_url_verified(
3822+
def test_new_release_url_verified(
38233823
self, monkeypatch, pyramid_config, db_request, metrics, url, expected
38243824
):
38253825
project = ProjectFactory.create()
@@ -3878,6 +3878,86 @@ def test_release_url_verified(
38783878
assert release_url is not None
38793879
assert release_url.verified == expected
38803880

3881+
def test_new_publisher_verifies_existing_release_url(
3882+
self,
3883+
monkeypatch,
3884+
pyramid_config,
3885+
db_request,
3886+
metrics,
3887+
):
3888+
repo_name = "my_new_repo"
3889+
verified_url = "https://github.com/foo/bar"
3890+
unverified_url = f"https://github.com/foo/{repo_name}"
3891+
3892+
project = ProjectFactory.create()
3893+
release = ReleaseFactory.create(project=project, version="1.0")
3894+
# We start with an existing release, with one verified URL and one unverified
3895+
# URL. Uploading a new file with a Trusted Publisher that matches the unverified
3896+
# URL should mark it as verified.
3897+
release.project_urls = {
3898+
"verified_url": {"url": verified_url, "verified": True},
3899+
"unverified_url": {"url": unverified_url, "verified": False},
3900+
}
3901+
publisher = GitHubPublisherFactory.create(projects=[project])
3902+
publisher.repository_owner = "foo"
3903+
publisher.repository_name = repo_name
3904+
claims = {"sha": "somesha"}
3905+
identity = PublisherTokenContext(publisher, SignedClaims(claims))
3906+
db_request.oidc_publisher = identity.publisher
3907+
db_request.oidc_claims = identity.claims
3908+
3909+
db_request.db.add(Classifier(classifier="Environment :: Other Environment"))
3910+
db_request.db.add(Classifier(classifier="Programming Language :: Python"))
3911+
3912+
filename = "{}-{}.tar.gz".format(project.name, "1.0")
3913+
3914+
pyramid_config.testing_securitypolicy(identity=identity)
3915+
db_request.user_agent = "warehouse-tests/6.6.6"
3916+
db_request.POST = MultiDict(
3917+
{
3918+
"metadata_version": "1.2",
3919+
"name": project.name,
3920+
"version": "1.0",
3921+
"summary": "This is my summary!",
3922+
"filetype": "sdist",
3923+
"md5_digest": _TAR_GZ_PKG_MD5,
3924+
"content": pretend.stub(
3925+
filename=filename,
3926+
file=io.BytesIO(_TAR_GZ_PKG_TESTDATA),
3927+
type="application/tar",
3928+
),
3929+
}
3930+
)
3931+
db_request.POST.extend(
3932+
[
3933+
("classifiers", "Environment :: Other Environment"),
3934+
("classifiers", "Programming Language :: Python"),
3935+
("requires_dist", "foo"),
3936+
("requires_dist", "bar (>1.0)"),
3937+
("requires_external", "Cheese (>1.0)"),
3938+
("provides", "testing"),
3939+
]
3940+
)
3941+
db_request.POST.add("project_urls", f"verified_url, {verified_url}")
3942+
db_request.POST.add("project_urls", f"unverified_url, {unverified_url}")
3943+
3944+
storage_service = pretend.stub(store=lambda path, filepath, meta: None)
3945+
db_request.find_service = lambda svc, name=None, context=None: {
3946+
IFileStorage: storage_service,
3947+
IMetricsService: metrics,
3948+
}.get(svc)
3949+
3950+
legacy.file_upload(db_request)
3951+
3952+
# After successful upload, the Release should have now both URLs verified
3953+
release_urls = (
3954+
db_request.db.query(ReleaseURL).filter(Release.project == project).all()
3955+
)
3956+
release_urls = {r.name: r.verified for r in release_urls}
3957+
assert "verified_url" in release_urls and "unverified_url" in release_urls
3958+
assert release_urls["verified_url"]
3959+
assert release_urls["unverified_url"]
3960+
38813961
@pytest.mark.parametrize(
38823962
"version, expected_version",
38833963
[

warehouse/forklift/legacy.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,7 @@ def file_upload(request):
817817
}
818818
)
819819
try:
820+
is_new_release = False
820821
canonical_version = packaging.utils.canonicalize_version(meta.version)
821822
release = (
822823
request.db.query(Release)
@@ -908,6 +909,7 @@ def file_upload(request):
908909
uploaded_via=request.user_agent,
909910
)
910911
request.db.add(release)
912+
is_new_release = True
911913

912914
# TODO: This should be handled by some sort of database trigger or
913915
# a SQLAlchemy hook or the like instead of doing it inline in
@@ -1307,6 +1309,19 @@ def file_upload(request):
13071309
},
13081310
)
13091311

1312+
# For existing releases, we check if any of the existing project URLs are unverified
1313+
# and have been verified in the current upload. In that case, we mark them as
1314+
# verified.
1315+
if not is_new_release and project_urls:
1316+
for name, release_url in release._project_urls.items():
1317+
if (
1318+
not release_url.verified
1319+
and name in project_urls
1320+
and project_urls[name]["url"] == release_url.url
1321+
and project_urls[name]["verified"]
1322+
):
1323+
release_url.verified = True
1324+
13101325
# Check if the user has any 2FA methods enabled, and if not, email them.
13111326
if request.user and not request.user.has_two_factor:
13121327
warnings.append("Two factor authentication is not enabled for your account.")

warehouse/migrations/versions/26455e3712a2_create_verified_field_for_releaseurl.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
create verified field for ReleaseUrl
1414
1515
Revision ID: 26455e3712a2
16-
Revises: b14df478c48f
16+
Revises: bb6943882aa9
1717
Create Date: 2024-04-30 18:40:17.149050
1818
"""
1919

@@ -22,7 +22,7 @@
2222
from alembic import op
2323

2424
revision = "26455e3712a2"
25-
down_revision = "b14df478c48f"
25+
down_revision = "bb6943882aa9"
2626

2727

2828
def upgrade():

0 commit comments

Comments
 (0)