Skip to content

Commit dce704b

Browse files
committed
chore: minor fixes
Signed-off-by: Ben Selwyn-Smith <[email protected]>
1 parent e0c3fec commit dce704b

File tree

4 files changed

+99
-44
lines changed

4 files changed

+99
-44
lines changed

src/macaron/slsa_analyzer/analyzer.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ def run_single(
512512
logger.debug("Failed to parse repository path as URL: %s", error)
513513
if url and url.hostname == "github.com":
514514
artifact_hash = self.get_artifact_hash(
515-
parsed_purl, local_artifact_dirs, hashlib.sha256(), all_package_registries
515+
parsed_purl, local_artifact_dirs, hashlib.sha256(), package_registries_info
516516
)
517517
if artifact_hash:
518518
git_attestation_dict = git_service.api_client.get_attestation(
@@ -991,7 +991,7 @@ def get_artifact_hash(
991991
purl: PackageURL,
992992
cached_artifacts: list[str] | None,
993993
hash_algorithm: Any,
994-
all_package_registries: list[PackageRegistryInfo],
994+
package_registries_info: list[PackageRegistryInfo],
995995
) -> str | None:
996996
"""Get the hash of the artifact found from the passed PURL using local or remote files.
997997
@@ -1003,7 +1003,7 @@ def get_artifact_hash(
10031003
The list of local files that match the PURL.
10041004
hash_algorithm: Any
10051005
The hash algorithm to use.
1006-
all_package_registries: list[PackageRegistryInfo]
1006+
package_registries_info: list[PackageRegistryInfo]
10071007
The list of package registry information.
10081008
10091009
Returns
@@ -1049,7 +1049,7 @@ def get_artifact_hash(
10491049
registry_info = next(
10501050
(
10511051
info
1052-
for info in all_package_registries
1052+
for info in package_registries_info
10531053
if info.package_registry == pypi_registry and info.build_tool_name in {"pip", "poetry"}
10541054
),
10551055
None,

src/macaron/slsa_analyzer/checks/detect_malicious_metadata_check.py

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from macaron.slsa_analyzer.checks.check_result import CheckResultData, CheckResultType, Confidence, JustificationType
3333
from macaron.slsa_analyzer.package_registry.deps_dev import APIAccessError, DepsDevService
3434
from macaron.slsa_analyzer.package_registry.osv_dev import OSVDevService
35-
from macaron.slsa_analyzer.package_registry.pypi_registry import PyPIPackageJsonAsset, PyPIRegistry
3635
from macaron.slsa_analyzer.package_registry.pypi_registry import (
3736
PyPIPackageJsonAsset,
3837
PyPIRegistry,

src/macaron/slsa_analyzer/package_registry/maven_central_registry.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,15 @@ def get_artifact_hash(self, purl: PackageURL, hash_algorithm: Any) -> str | None
274274
str | None
275275
The hash of the artifact, or None if not found.
276276
"""
277-
if not (purl.namespace and purl.version):
277+
if not purl.namespace:
278278
return None
279279

280-
artifact_path = construct_maven_repository_path(purl.namespace, purl.name, purl.version)
281280
file_name = MavenCentralRegistry.get_artifact_file_name(purl)
282-
if not file_name:
281+
if not (purl.version and file_name):
283282
return None
284283

285284
# Maven supports but does not require a sha256 hash of uploaded artifacts.
285+
artifact_path = construct_maven_repository_path(purl.namespace, purl.name, purl.version)
286286
artifact_url = self.registry_url + "/" + artifact_path + "/" + file_name
287287
sha256_url = artifact_url + ".sha256"
288288
logger.debug("Search for artifact hash using URL: %s", [sha256_url, artifact_url])

tests/slsa_analyzer/package_registry/test_maven_central_registry.py

+92-36
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
import os
88
import urllib.parse
99
from datetime import datetime
10+
from hashlib import sha256
1011
from pathlib import Path
1112

1213
import pytest
14+
from packageurl import PackageURL
1315
from pytest_httpserver import HTTPServer
1416

17+
from macaron.artifact.maven import construct_maven_repository_path
1518
from macaron.config.defaults import load_defaults
1619
from macaron.errors import ConfigurationError, InvalidHTTPResponseError
1720
from macaron.slsa_analyzer.package_registry.maven_central_registry import MavenCentralRegistry
@@ -35,6 +38,28 @@ def maven_central_instance() -> MavenCentralRegistry:
3538
)
3639

3740

41+
@pytest.fixture(name="maven_service")
42+
def maven_service_(httpserver: HTTPServer, tmp_path: Path) -> None:
43+
"""Set up the Maven httpserver."""
44+
base_url_parsed = urllib.parse.urlparse(httpserver.url_for(""))
45+
46+
user_config_input = f"""
47+
[package_registry.maven_central]
48+
request_timeout = 20
49+
search_netloc = {base_url_parsed.netloc}
50+
search_scheme = {base_url_parsed.scheme}
51+
registry_url_netloc = {base_url_parsed.netloc}
52+
registry_url_scheme = {base_url_parsed.scheme}
53+
"""
54+
user_config_path = os.path.join(tmp_path, "config.ini")
55+
with open(user_config_path, "w", encoding="utf-8") as user_config_file:
56+
user_config_file.write(user_config_input)
57+
# We don't have to worry about modifying the ``defaults`` object causing test
58+
# pollution here, since we reload the ``defaults`` object before every test with the
59+
# ``setup_test`` fixture.
60+
load_defaults(user_config_path)
61+
62+
3863
def test_load_defaults(tmp_path: Path) -> None:
3964
"""Test the ``load_defaults`` method."""
4065
user_config_path = os.path.join(tmp_path, "config.ini")
@@ -150,31 +175,14 @@ def test_is_detected(
150175
def test_find_publish_timestamp(
151176
resources_path: Path,
152177
httpserver: HTTPServer,
153-
tmp_path: Path,
178+
maven_service: dict, # pylint: disable=unused-argument
154179
purl: str,
155180
mc_json_path: str,
156181
query_string: str,
157182
expected_timestamp: str,
158183
) -> None:
159184
"""Test that the function finds the timestamp correctly."""
160-
base_url_parsed = urllib.parse.urlparse(httpserver.url_for(""))
161-
162185
maven_central = MavenCentralRegistry()
163-
164-
# Set up responses of solrsearch endpoints using the httpserver plugin.
165-
user_config_input = f"""
166-
[package_registry.maven_central]
167-
request_timeout = 20
168-
search_netloc = {base_url_parsed.netloc}
169-
search_scheme = {base_url_parsed.scheme}
170-
"""
171-
user_config_path = os.path.join(tmp_path, "config.ini")
172-
with open(user_config_path, "w", encoding="utf-8") as user_config_file:
173-
user_config_file.write(user_config_input)
174-
# We don't have to worry about modifying the ``defaults`` object causing test
175-
# pollution here, since we reload the ``defaults`` object before every test with the
176-
# ``setup_test`` fixture.
177-
load_defaults(user_config_path)
178186
maven_central.load_defaults()
179187

180188
with open(os.path.join(resources_path, "maven_central_files", mc_json_path), encoding="utf8") as page:
@@ -208,35 +216,19 @@ def test_find_publish_timestamp(
208216
def test_find_publish_timestamp_errors(
209217
resources_path: Path,
210218
httpserver: HTTPServer,
211-
tmp_path: Path,
219+
maven_service: dict, # pylint: disable=unused-argument
212220
purl: str,
213221
mc_json_path: str,
214222
expected_msg: str,
215223
) -> None:
216224
"""Test that the function handles errors correctly."""
217-
base_url_parsed = urllib.parse.urlparse(httpserver.url_for(""))
218-
219225
maven_central = MavenCentralRegistry()
220-
221-
# Set up responses of solrsearch endpoints using the httpserver plugin.
222-
user_config_input = f"""
223-
[package_registry.maven_central]
224-
request_timeout = 20
225-
search_netloc = {base_url_parsed.netloc}
226-
search_scheme = {base_url_parsed.scheme}
227-
"""
228-
user_config_path = os.path.join(tmp_path, "config.ini")
229-
with open(user_config_path, "w", encoding="utf-8") as user_config_file:
230-
user_config_file.write(user_config_input)
231-
# We don't have to worry about modifying the ``defaults`` object causing test
232-
# pollution here, since we reload the ``defaults`` object before every test with the
233-
# ``setup_test`` fixture.
234-
load_defaults(user_config_path)
235226
maven_central.load_defaults()
236227

237228
with open(os.path.join(resources_path, "maven_central_files", mc_json_path), encoding="utf8") as page:
238229
mc_json_response = json.load(page)
239230

231+
# Set up responses of solrsearch endpoints using the httpserver plugin.
240232
httpserver.expect_request(
241233
"/solrsearch/select",
242234
query_string="q=g:org.apache.logging.log4j+AND+a:log4j-core+AND+v:3.0.0-beta2&core=gav&rows=1&wt=json",
@@ -245,3 +237,67 @@ def test_find_publish_timestamp_errors(
245237
pat = f"^{expected_msg}"
246238
with pytest.raises(InvalidHTTPResponseError, match=pat):
247239
maven_central.find_publish_timestamp(purl=purl)
240+
241+
242+
def test_get_artifact_file_name() -> None:
243+
"""Test the artifact file name function."""
244+
assert not MavenCentralRegistry().get_artifact_file_name(PackageURL.from_string("pkg:maven/test/example"))
245+
246+
assert (
247+
MavenCentralRegistry().get_artifact_file_name(PackageURL.from_string("pkg:maven/text/example@1"))
248+
== "example-1.jar"
249+
)
250+
251+
252+
@pytest.mark.parametrize("purl_string", ["pkg:maven/example", "pkg:maven/example/test", "pkg:maven/example/test@1"])
253+
def test_get_artifact_hash_failures(
254+
httpserver: HTTPServer, maven_service: dict, purl_string: str # pylint: disable=unused-argument
255+
) -> None:
256+
"""Test failures of get artifact hash."""
257+
purl = PackageURL.from_string(purl_string)
258+
259+
maven_registry = MavenCentralRegistry()
260+
maven_registry.load_defaults()
261+
262+
if (
263+
purl.namespace
264+
and purl.version
265+
and (file_name := MavenCentralRegistry().get_artifact_file_name(purl))
266+
and file_name
267+
):
268+
artifact_path = "/" + construct_maven_repository_path(purl.namespace, purl.name, purl.version) + "/" + file_name
269+
hash_algorithm = sha256()
270+
hash_algorithm.update(b"example_data")
271+
expected_hash = hash_algorithm.hexdigest()
272+
httpserver.expect_request(artifact_path + ".sha256").respond_with_data(expected_hash)
273+
httpserver.expect_request(artifact_path).respond_with_data(b"example_data_2")
274+
275+
result = maven_registry.get_artifact_hash(purl, sha256())
276+
277+
assert not result
278+
279+
280+
def test_get_artifact_hash_success(
281+
httpserver: HTTPServer, maven_service: dict # pylint: disable=unused-argument
282+
) -> None:
283+
"""Test success of get artifact hash."""
284+
purl = PackageURL.from_string("pkg:maven/example/test@1")
285+
assert purl.namespace
286+
assert purl.version
287+
288+
maven_registry = MavenCentralRegistry()
289+
maven_registry.load_defaults()
290+
291+
file_name = MavenCentralRegistry().get_artifact_file_name(purl)
292+
assert file_name
293+
294+
artifact_path = "/" + construct_maven_repository_path(purl.namespace, purl.name, purl.version) + "/" + file_name
295+
hash_algorithm = sha256()
296+
hash_algorithm.update(b"example_data")
297+
expected_hash = hash_algorithm.hexdigest()
298+
httpserver.expect_request(artifact_path + ".sha256").respond_with_data(expected_hash)
299+
httpserver.expect_request(artifact_path).respond_with_data(b"example_data")
300+
301+
result = maven_registry.get_artifact_hash(purl, sha256())
302+
303+
assert result

0 commit comments

Comments
 (0)