@@ -1961,7 +1961,9 @@ def test_upload_fails_with_existing_filename_diff_content(
1961
1961
),
1962
1962
}
1963
1963
)
1964
-
1964
+ blake2_256_digest = hashlib .blake2b (
1965
+ file_content .getvalue (), digest_size = 256 // 8
1966
+ ).hexdigest ()
1965
1967
db_request .db .add (
1966
1968
FileFactory .create (
1967
1969
release = release ,
@@ -1985,7 +1987,9 @@ def test_upload_fails_with_existing_filename_diff_content(
1985
1987
assert db_request .help_url .calls == [pretend .call (_anchor = "file-name-reuse" )]
1986
1988
assert resp .status_code == 400
1987
1989
assert resp .status == (
1988
- "400 File already exists. See /the/help/url/ for more information."
1990
+ f"400 File already exists ({ filename !r} , "
1991
+ f"with blake2_256 hash { blake2_256_digest !r} ). "
1992
+ "See /the/help/url/ for more information."
1989
1993
)
1990
1994
1991
1995
def test_upload_fails_with_diff_filename_same_blake2 (
@@ -2017,15 +2021,16 @@ def test_upload_fails_with_diff_filename_same_blake2(
2017
2021
}
2018
2022
)
2019
2023
2024
+ blake2_256_digest = hashlib .blake2b (
2025
+ file_content .getvalue (), digest_size = 256 // 8
2026
+ ).hexdigest ()
2020
2027
db_request .db .add (
2021
2028
FileFactory .create (
2022
2029
release = release ,
2023
2030
filename = filename ,
2024
2031
md5_digest = hashlib .md5 (file_content .getvalue ()).hexdigest (),
2025
2032
sha256_digest = hashlib .sha256 (file_content .getvalue ()).hexdigest (),
2026
- blake2_256_digest = hashlib .blake2b (
2027
- file_content .getvalue (), digest_size = 256 // 8
2028
- ).hexdigest (),
2033
+ blake2_256_digest = blake2_256_digest ,
2029
2034
path = "source/{name[0]}/{name}/{filename}" .format (
2030
2035
name = project .name , filename = filename
2031
2036
),
@@ -2041,7 +2046,9 @@ def test_upload_fails_with_diff_filename_same_blake2(
2041
2046
assert db_request .help_url .calls == [pretend .call (_anchor = "file-name-reuse" )]
2042
2047
assert resp .status_code == 400
2043
2048
assert resp .status == (
2044
- "400 File already exists. See /the/help/url/ for more information."
2049
+ f"400 File already exists ({ db_request .POST ['content' ].filename !r} , "
2050
+ f"with blake2_256 hash { blake2_256_digest !r} ). "
2051
+ "See /the/help/url/ for more information."
2045
2052
)
2046
2053
2047
2054
@pytest .mark .parametrize (
@@ -4536,12 +4543,145 @@ def test_missing_trailing_slash_redirect(pyramid_request):
4536
4543
"https://github.com" ,
4537
4544
False ,
4538
4545
),
4539
- ( # Publisher URL is None
4540
- "https://github.com/owner/project" ,
4541
- None ,
4546
+ ],
4547
+ )
4548
+ def test_verify_url_with_trusted_publisher (url , publisher_url , expected ):
4549
+ assert legacy ._verify_url_with_trusted_publisher (url , publisher_url ) == expected
4550
+
4551
+
4552
+ @pytest .mark .parametrize (
4553
+ ("url" , "project_name" , "project_normalized_name" , "expected" ),
4554
+ [
4555
+ ( # PyPI /project/ case
4556
+ "https://pypi.org/project/myproject" ,
4557
+ "myproject" ,
4558
+ "myproject" ,
4559
+ True ,
4560
+ ),
4561
+ ( # PyPI /p/ case
4562
+ "https://pypi.org/p/myproject" ,
4563
+ "myproject" ,
4564
+ "myproject" ,
4565
+ True ,
4566
+ ),
4567
+ ( # pypi.python.org /project/ case
4568
+ "https://pypi.python.org/project/myproject" ,
4569
+ "myproject" ,
4570
+ "myproject" ,
4571
+ True ,
4572
+ ),
4573
+ ( # pypi.python.org /p/ case
4574
+ "https://pypi.python.org/p/myproject" ,
4575
+ "myproject" ,
4576
+ "myproject" ,
4577
+ True ,
4578
+ ),
4579
+ ( # python.org/pypi/ case
4580
+ "https://python.org/pypi/myproject" ,
4581
+ "myproject" ,
4582
+ "myproject" ,
4583
+ True ,
4584
+ ),
4585
+ ( # PyPI /project/ case
4586
+ "https://pypi.org/project/myproject" ,
4587
+ "myproject" ,
4588
+ "myproject" ,
4589
+ True ,
4590
+ ),
4591
+ ( # Normalized name differs from URL
4592
+ "https://pypi.org/project/my_project" ,
4593
+ "my_project" ,
4594
+ "my-project" ,
4595
+ True ,
4596
+ ),
4597
+ ( # Normalized name same as URL
4598
+ "https://pypi.org/project/my-project" ,
4599
+ "my_project" ,
4600
+ "my-project" ,
4601
+ True ,
4602
+ ),
4603
+ ( # Trailing slash
4604
+ "https://pypi.org/project/myproject/" ,
4605
+ "myproject" ,
4606
+ "myproject" ,
4607
+ True ,
4608
+ ),
4609
+ ( # Domains are case insensitive
4610
+ "https://PyPI.org/project/myproject" ,
4611
+ "myproject" ,
4612
+ "myproject" ,
4613
+ True ,
4614
+ ),
4615
+ ( # Paths are case-sensitive
4616
+ "https://pypi.org/Project/myproject" ,
4617
+ "myproject" ,
4618
+ "myproject" ,
4619
+ False ,
4620
+ ),
4621
+ ( # Wrong domain
4622
+ "https://example.com/project/myproject" ,
4623
+ "myproject" ,
4624
+ "myproject" ,
4625
+ False ,
4626
+ ),
4627
+ ( # Wrong path
4628
+ "https://pypi.org/something/myproject" ,
4629
+ "myproject" ,
4630
+ "myproject" ,
4631
+ False ,
4632
+ ),
4633
+ ( # Path has extra components
4634
+ "https://pypi.org/something/myproject/something" ,
4635
+ "myproject" ,
4636
+ "myproject" ,
4637
+ False ,
4638
+ ),
4639
+ ( # Wrong package name
4640
+ "https://pypi.org/project/otherproject" ,
4641
+ "myproject" ,
4642
+ "myproject" ,
4643
+ False ,
4644
+ ),
4645
+ ( # Similar package name
4646
+ "https://pypi.org/project/myproject" ,
4647
+ "myproject2" ,
4648
+ "myproject2" ,
4649
+ False ,
4650
+ ),
4651
+ ( # Similar package name
4652
+ "https://pypi.org/project/myproject2" ,
4653
+ "myproject" ,
4654
+ "myproject" ,
4542
4655
False ,
4543
4656
),
4544
4657
],
4545
4658
)
4546
- def test_verify_url (url , publisher_url , expected ):
4547
- assert legacy ._verify_url (url , publisher_url ) == expected
4659
+ def test_verify_url_pypi (url , project_name , project_normalized_name , expected ):
4660
+ assert (
4661
+ legacy ._verify_url_pypi (url , project_name , project_normalized_name ) == expected
4662
+ )
4663
+
4664
+
4665
+ def test_verify_url ():
4666
+ # `_verify_url` is just a helper function that calls `_verify_url_pypi` and
4667
+ # `_verify_url_with_trusted_publisher`, where the actual verification logic lives.
4668
+ assert legacy ._verify_url (
4669
+ url = "https://pypi.org/project/myproject/" ,
4670
+ publisher_url = None ,
4671
+ project_name = "myproject" ,
4672
+ project_normalized_name = "myproject" ,
4673
+ )
4674
+
4675
+ assert legacy ._verify_url (
4676
+ url = "https://github.com/org/myproject/issues" ,
4677
+ publisher_url = "https://github.com/org/myproject" ,
4678
+ project_name = "myproject" ,
4679
+ project_normalized_name = "myproject" ,
4680
+ )
4681
+
4682
+ assert not legacy ._verify_url (
4683
+ url = "example.com" ,
4684
+ publisher_url = "https://github.com/or/myproject" ,
4685
+ project_name = "myproject" ,
4686
+ project_normalized_name = "myproject" ,
4687
+ )
0 commit comments