Skip to content

Commit

Permalink
fix: block terminal prompts in find source (#918)
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Selwyn-Smith <[email protected]>
  • Loading branch information
benmss authored Nov 18, 2024
1 parent ab0dd3e commit b65f0db
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
13 changes: 5 additions & 8 deletions src/macaron/repo_finder/repo_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import os
from urllib.parse import ParseResult, urlunparse

import git
from packageurl import PackageURL

from macaron.config.defaults import defaults
Expand All @@ -47,7 +46,7 @@
from macaron.repo_finder.repo_finder_deps_dev import DepsDevRepoFinder
from macaron.repo_finder.repo_finder_java import JavaRepoFinder
from macaron.repo_finder.repo_utils import generate_report, prepare_repo
from macaron.slsa_analyzer.git_url import GIT_REPOS_DIR
from macaron.slsa_analyzer.git_url import GIT_REPOS_DIR, list_remote_references

logger: logging.Logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -170,11 +169,11 @@ def find_source(purl_string: str, input_repo: str | None) -> bool:

# Disable other loggers for cleaner output.
logging.getLogger("macaron.slsa_analyzer.analyzer").disabled = True
logging.getLogger("macaron.slsa_analyzer.git_url").disabled = True

if defaults.getboolean("repofinder", "find_source_should_clone"):
logger.debug("Preparing repo: %s", found_repo)
repo_dir = os.path.join(global_config.output_path, GIT_REPOS_DIR)
logging.getLogger("macaron.slsa_analyzer.git_url").disabled = True
git_obj = prepare_repo(
repo_dir,
found_repo,
Expand Down Expand Up @@ -233,12 +232,10 @@ def get_tags_via_git_remote(repo: str) -> dict[str, str] | None:
dict[str]
A dictionary of tags mapped to their commits, or None if the operation failed..
"""
tags = {}
try:
tag_data = git.cmd.Git().ls_remote("--tags", repo)
except git.exc.GitCommandError as error:
logger.debug("Failed to retrieve tags: %s", error)
tag_data = list_remote_references(["--tags"], repo)
if not tag_data:
return None
tags = {}

for tag_line in tag_data.splitlines():
tag_line = tag_line.strip()
Expand Down
42 changes: 42 additions & 0 deletions src/macaron/slsa_analyzer/git_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pydriller.git import Git

from macaron.config.defaults import defaults
from macaron.config.global_config import global_config
from macaron.environment_variables import get_patched_env
from macaron.errors import CloneError

Expand Down Expand Up @@ -376,6 +377,47 @@ def clone_remote_repo(clone_dir: str, url: str) -> Repo | None:
return Repo(path=clone_dir)


def list_remote_references(arguments: list[str], repo: str) -> str | None:
"""Retrieve references from a remote repository using Git's ``ls-remote``.
Parameters
----------
arguments: list[str]
The arguments to pass into the command.
repo: str
The repository to run the command on.
Returns
-------
str
The result of the command.
"""
try:
result = subprocess.run( # nosec B603
args=["git", "ls-remote"] + arguments + [repo],
capture_output=True,
# By setting stdin to /dev/null and using a new session, we prevent all possible user input prompts.
stdin=subprocess.DEVNULL,
start_new_session=True,
cwd=global_config.output_path,
check=False,
)
except (subprocess.CalledProcessError, OSError):
return None

if result.returncode != 0:
error_string = result.stderr.decode("utf-8").strip()
if error_string.startswith("fatal: could not read Username"):
# Occurs when a repository cannot be accessed either because it does not exist, or it requires a login
# that is blocked.
logger.error("Could not access repository: %s", repo)
else:
logger.error("Failed to retrieve remote references from repo: %s", repo)
return None

return result.stdout.decode("utf-8")


def resolve_local_path(start_dir: str, local_path: str) -> str:
"""Resolve the local path and check if it's within a directory.
Expand Down
20 changes: 20 additions & 0 deletions tests/integration/cases/find_source_fail/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2024 - 2024, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.

description: |
Analyzing the find source command on a non-existent repository.
tags:
- macaron-python-package
- macaron-docker-image

steps:
- name: Run macaron find source on private repository
kind: find-source
options:
command_args:
- -purl
- pkg:maven/com.example/[email protected]
- -rp
- https://github.com/oracle/hopefully-this-repository-will-never-exist-0
expect_fail: true

0 comments on commit b65f0db

Please sign in to comment.