Skip to content

Commit

Permalink
chore: adjust way in which discovery functions are called; use partia…
Browse files Browse the repository at this point in the history
…l for Callables with variables args

Signed-off-by: Ben Selwyn-Smith <benselwynsmith@googlemail.com>
  • Loading branch information
benmss committed Jul 10, 2024
1 parent e3d2803 commit 4f32d1e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 90 deletions.
123 changes: 50 additions & 73 deletions src/macaron/repo_finder/provenance_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import logging
import os
import tempfile
from collections.abc import Callable
from inspect import signature
from typing import Any
from functools import partial

from packageurl import PackageURL

Expand Down Expand Up @@ -38,78 +36,69 @@ def __init__(self) -> None:
elif isinstance(registry, JFrogMavenRegistry):
self.jfrog_registry = registry

def find_provenance(
self,
purl: PackageURL,
discovery_functions: list[Callable[..., list[InTotoPayload]]] | None = None,
parameter_lists: list[list[Any]] | None = None,
) -> list[InTotoPayload]:
def find_provenance(self, purl: PackageURL) -> list[InTotoPayload]:
"""Find the provenance file(s) of the passed PURL.
Parameters
----------
purl: PackageURL
The PURL to find provenance for.
discovery_functions: list[Callable[..., list[InTotoPayload]]] | None
A list of discovery functions to use for the given PURL, or None if the default should be used instead.
parameter_lists: list[Any] | None
The lists of parameters to pass to the callables, or None if the default should be used instead.
Returns
-------
list[InTotoPayload]
The provenance payload, or an empty list if not found.
"""
if not discovery_functions:
if determine_abstract_purl_type(purl) == AbstractPurlType.REPOSITORY:
# Do not perform default discovery for repository type targets.
if determine_abstract_purl_type(purl) == AbstractPurlType.REPOSITORY:
# Do not perform default discovery for repository type targets.
return []

if purl.type == "npm":
if not self.npm_registry:
logger.debug("Missing npm registry to find provenance in.")
return []

if purl.type == "npm":
if not self.npm_registry:
logger.debug("Missing npm registry to find provenance in.")
return []
discovery_functions = [find_npm_provenance]
parameter_lists = [[purl, self.npm_registry]]

elif purl.type in ["gradle", "maven"]:
if self.jfrog_registry:
discovery_functions = [find_gav_provenance]
parameter_lists = [[purl, self.jfrog_registry]]
discovery_functions = [partial(find_npm_provenance, purl, self.npm_registry)]
return self._find_provenance(discovery_functions)

if purl.type in ["gradle", "maven"]:
if not self.jfrog_registry:
logger.debug("Missing JFrog registry to find provenance in.")
else:
logger.debug("Provenance finding not supported for PURL type: %s", purl.type)
return []

discovery_functions = [partial(find_gav_provenance, purl, self.jfrog_registry)]
return self._find_provenance(discovery_functions)

# TODO add other possible discovery functions.
logger.debug("Provenance finding not supported for PURL type: %s", purl.type)
return []

def _find_provenance(self, discovery_functions: list[partial[list[InTotoPayload]]]) -> list[InTotoPayload]:
"""Find the provenance file(s) using the passed discovery functions.
Parameters
----------
discovery_functions: list[partial[list[InTotoPayload]]]
A list of discovery functions to use to find the provenance.
Returns
-------
list[InTotoPayload]
The provenance payload(s) from the first successful function, or an empty list if none were.
"""
if not discovery_functions:
logger.debug("No provenance discovery functions provided/found for %s", purl)
return []

for index, discovery_function in enumerate(discovery_functions):
parameter_list = parameter_lists[index] if parameter_lists and index < len(parameter_lists) else [purl]
function_signature = signature(discovery_function)
if len(function_signature.parameters) != len(parameter_list):
logger.debug(
"Mismatch between function and parameters: %s vs. %s",
len(function_signature.parameters),
len(parameter_list),
)
continue

provenance = discovery_function(*parameter_list)
for discovery_function in discovery_functions:
provenance = discovery_function()

if provenance:
return provenance

logger.debug("No provenance found.")
return []

def verify_provenance(
self,
purl: PackageURL,
provenance: list[InTotoPayload],
verification_function: Callable[[PackageURL, list[InTotoPayload]], bool] | None = None,
parameters: list[Any] | None = None,
) -> bool:
def verify_provenance(self, purl: PackageURL, provenance: list[InTotoPayload]) -> bool:
"""Verify the passed provenance.
Parameters
Expand All @@ -118,40 +107,28 @@ def verify_provenance(
The PURL of the analysis target.
provenance: list[InTotoPayload]
The list of provenance.
verification_function: list[Callable[[PackageURL, list[InTotoPayload]], bool]] | None
A callable that should verify the provenance, or None if the default callable should be used instead.
parameters: list[Any] | None
The list of parameters to pass to the callable, or None.
Returns
-------
bool
True if the provenance could be verified, or False otherwise.
"""
if not verification_function:
if determine_abstract_purl_type(purl) == AbstractPurlType.REPOSITORY:
# Do not perform default verification for repository type targets.
return False

if purl.type == "npm":
verification_function = verify_npm_provenance
parameters = [purl, provenance]
else:
logger.debug("Provenance verification not supported for PURL type: %s", purl.type)

if not verification_function:
logger.debug("No provenance verification function provided/found for %s", purl)
if determine_abstract_purl_type(purl) == AbstractPurlType.REPOSITORY:
# Do not perform default verification for repository type targets.
return False

if not parameters:
logger.debug("No parameter arguments for provenance verification function.")
return False
verification_function = None

if purl.type == "npm":
verification_function = partial(verify_npm_provenance, purl, provenance)

provenance_verified = verification_function(*parameters)
# TODO other verification functions go here.

if not provenance_verified:
logger.debug("Provenance could not be verified.")
return provenance_verified
if verification_function:
return verification_function()

logger.debug("Provenance verification not supported for PURL type: %s", purl.type)
return False


def find_npm_provenance(purl: PackageURL, registry: NPMRegistry) -> list[InTotoPayload]:
Expand Down
17 changes: 0 additions & 17 deletions tests/repo_finder/test_provenance_finder.py

This file was deleted.

0 comments on commit 4f32d1e

Please sign in to comment.