Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions checkov/common/goget/github/get_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import logging
import re
import shutil
import os

from checkov.common.goget.base_getter import BaseGetter
from checkov.common.resource_code_logger_filter import add_resource_code_filter_to_logger
from checkov.common.util.contextmanagers import temp_environ
from checkov.common.util.env_vars_config import env_vars_config

try:
from git import Repo
Expand Down Expand Up @@ -79,12 +79,19 @@ def do_get(self) -> str:
def _clone(self, git_url: str, clone_dir: str) -> None:
self.logger.info(f"cloning {git_url} to {clone_dir}")
with temp_environ(GIT_TERMINAL_PROMPT="0"): # disables user prompts originating from GIT
if os.getenv('PROXY_URL'):
self.logger.info(f'Performing clone through proxy - {os.getenv("PROXY_URL")}')
with temp_environ(GIT_SSL_CAINFO=os.getenv('PROXY_CA_PATH'),
https_proxy=os.getenv('PROXY_URL'),
GIT_CONFIG_PARAMETERS=f"'http.extraHeader={os.getenv('PROXY_HEADER_KEY')}:{os.getenv('PROXY_HEADER_VALUE')}'"):
if env_vars_config.PROXY_URL:
self.logger.info(f'Performing clone through proxy - {env_vars_config.PROXY_URL}')
with temp_environ(GIT_SSL_CAINFO=env_vars_config.PROXY_CA_PATH,
https_proxy=env_vars_config.PROXY_URL,
GIT_CONFIG_PARAMETERS=f"'http.extraHeader={env_vars_config.PROXY_HEADER_KEY}:{env_vars_config.PROXY_HEADER_VALUE}'"):
self._clone_helper(clone_dir, git_url)
return
ca_bundle = env_vars_config.BC_CA_BUNDLE
if ca_bundle:
self.logger.info(f'Using custom CA bundle from BC_CA_BUNDLE: {ca_bundle}')
with temp_environ(GIT_SSL_CAINFO=ca_bundle):
self._clone_helper(clone_dir, git_url)
return
self._clone_helper(clone_dir, git_url)

def _clone_helper(self, clone_dir: str, git_url: str) -> None:
Expand Down
93 changes: 93 additions & 0 deletions tests/common/goget/test_goget_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,98 @@ def test_do_get_import_error(self):
getter.do_get()
self.assertEqual("Unable to load git module (is the git executable available?)", str(context.exception))

@patch('checkov.common.goget.github.get_git.Repo')
@patch('checkov.common.goget.github.get_git.env_vars_config')
def test_clone_with_bc_ca_bundle(self, mock_env_vars_config, mock_repo):
"""Test that BC_CA_BUNDLE env var sets GIT_SSL_CAINFO for git clone."""
# Arrange
mock_env_vars_config.BC_CA_BUNDLE = '/path/to/ca-bundle.crt'
mock_env_vars_config.PROXY_URL = None

url = "https://my-git.com/repo"
getter = GitGetter(url, create_clone_and_result_dirs=False)
getter.temp_dir = "/tmp/test"
mock_repo_instance = Mock()
mock_repo.clone_from.return_value = mock_repo_instance

captured_env = {}

def capture_env(*args, **kwargs):
captured_env['GIT_SSL_CAINFO'] = os.environ.get('GIT_SSL_CAINFO')
return mock_repo_instance

mock_repo.clone_from.side_effect = capture_env

# Act
getter.do_get()

# Assert
self.assertEqual('/path/to/ca-bundle.crt', captured_env.get('GIT_SSL_CAINFO'))
mock_repo.clone_from.assert_called_once()

@patch('checkov.common.goget.github.get_git.Repo')
@patch('checkov.common.goget.github.get_git.env_vars_config')
def test_clone_without_bc_ca_bundle(self, mock_env_vars_config, mock_repo):
"""Test that clone works without BC_CA_BUNDLE env var."""
# Arrange
mock_env_vars_config.BC_CA_BUNDLE = None
mock_env_vars_config.PROXY_URL = None

url = "https://my-git.com/repo"
getter = GitGetter(url, create_clone_and_result_dirs=False)
getter.temp_dir = "/tmp/test"
mock_repo_instance = Mock()
mock_repo.clone_from.return_value = mock_repo_instance

captured_env = {}

def capture_env(*args, **kwargs):
captured_env['GIT_SSL_CAINFO'] = os.environ.get('GIT_SSL_CAINFO')
return mock_repo_instance

mock_repo.clone_from.side_effect = capture_env

# Act
getter.do_get()

# Assert
self.assertIsNone(captured_env.get('GIT_SSL_CAINFO'))
mock_repo.clone_from.assert_called_once()

@patch('checkov.common.goget.github.get_git.Repo')
@patch('checkov.common.goget.github.get_git.env_vars_config')
def test_clone_proxy_takes_precedence_over_bc_ca_bundle(self, mock_env_vars_config, mock_repo):
"""Test that PROXY_URL settings take precedence over BC_CA_BUNDLE."""
# Arrange
mock_env_vars_config.PROXY_URL = 'http://proxy.example.com:8080'
mock_env_vars_config.PROXY_CA_PATH = '/path/to/proxy-ca.crt'
mock_env_vars_config.PROXY_HEADER_KEY = 'X-Custom-Header'
mock_env_vars_config.PROXY_HEADER_VALUE = 'custom-value'
mock_env_vars_config.BC_CA_BUNDLE = '/path/to/ca-bundle.crt'

url = "https://my-git.com/repo"
getter = GitGetter(url, create_clone_and_result_dirs=False)
getter.temp_dir = "/tmp/test"
mock_repo_instance = Mock()
mock_repo.clone_from.return_value = mock_repo_instance

captured_env = {}

def capture_env(*args, **kwargs):
captured_env['GIT_SSL_CAINFO'] = os.environ.get('GIT_SSL_CAINFO')
captured_env['https_proxy'] = os.environ.get('https_proxy')
return mock_repo_instance

mock_repo.clone_from.side_effect = capture_env

# Act
getter.do_get()

# Assert - PROXY_CA_PATH should be used, not BC_CA_BUNDLE
self.assertEqual('/path/to/proxy-ca.crt', captured_env.get('GIT_SSL_CAINFO'))
self.assertEqual('http://proxy.example.com:8080', captured_env.get('https_proxy'))
mock_repo.clone_from.assert_called_once()


if __name__ == '__main__':
unittest.main()
Loading