def test_deleted_secret(self): new_findings = secrets_collection_factory([ { 'secret': 'secret', 'lineno': 2, }, ]) baseline = secrets_collection_factory([ { 'secret': 'deleted_secret', 'lineno': 1, }, { 'secret': 'secret', 'lineno': 2, }, ]) is_successful = update_baseline_with_removed_secrets( new_findings, baseline, ['filename'], ) assert is_successful assert len(baseline.data) == 1 assert next(iter(baseline.data['filename'])).lineno == 2
def test_deleted_secret(self): new_findings = secrets_collection_factory([ { 'secret': 'secret', 'lineno': 2, }, ]) baseline = secrets_collection_factory([ { 'secret': 'deleted_secret', 'lineno': 1, }, { 'secret': 'secret', 'lineno': 2, }, ]) is_successful = trim_baseline_of_removed_secrets( new_findings, baseline, ['filename'], ) assert is_successful assert len(baseline.data) == 1 assert next(iter(baseline.data['filename'])).lineno == 2
def test_no_baseline_modifications(self, results_dict, baseline_dict): new_findings = secrets_collection_factory([results_dict]) baseline = secrets_collection_factory([baseline_dict]) assert not update_baseline_with_removed_secrets( new_findings, baseline, ['filename'], )
def test_no_baseline_modifications(self, results_dict, baseline_dict): new_findings = secrets_collection_factory([results_dict]) baseline = secrets_collection_factory([baseline_dict]) assert not trim_baseline_of_removed_secrets( new_findings, baseline, ['filename'], )
def test_nothing_new(self): # We want a secret, but just a default secret (no overriding parameters) new_findings = secrets_collection_factory([{}]) baseline = secrets_collection_factory([{}]) results = get_secrets_not_in_baseline(new_findings, baseline) # No expected results, because everything filtered out by baseline assert len(results.data) == 0 # Make sure that baseline didn't get modified either assert len(baseline.data) == 1 assert next(iter(baseline.data['filename'])).lineno == 1
def test_nothing_new(self): # We want a secret, but just a default secret (no overriding parameters) new_findings = secrets_collection_factory([{}]) baseline = secrets_collection_factory([{}]) results = get_secrets_not_in_baseline(new_findings, baseline) # No expected results, because everything filtered out by baseline assert len(results.data) == 0 # Make sure that baseline didn't get modified either assert len(baseline.data) == 1 assert next(iter(baseline.data['filename'])).lineno == 1
def setup(self): self.logic = secrets_collection_factory( secrets=[ { 'type_': 'A', 'lineno': 3, 'filename': 'fileA', }, { 'type_': 'B', 'lineno': 2, 'filename': 'fileA', }, { 'type_': 'C', 'lineno': 1, 'filename': 'fileB', }, ], plugins=( HexHighEntropyString(3), PrivateKeyDetector(), ), exclude_files_regex='foo', word_list_file='will_be_mocked.txt', word_list_hash='5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', )
def setup(self): self.logic = secrets_collection_factory( secrets=[ { 'type_': 'A', 'lineno': 3, 'filename': 'fileA', }, { 'type_': 'B', 'lineno': 2, 'filename': 'fileA', }, { 'type_': 'C', 'lineno': 1, 'filename': 'fileB', }, ], plugins=( HexHighEntropyString(3), PrivateKeyDetector(), ), exclude_files_regex='foo', )
def test_skip_ignored_file_extensions(self): logic = secrets_collection_factory( plugins=(MockPluginFixedValue(),), ) with mock_open('junk text here, as it does not matter'): skipped_extension = '.svg' assert not logic.scan_file('some' + skipped_extension)
def mock_baseline_initialize(): secrets = secrets_collection_factory() with mock.patch( 'detect_secrets.main.baseline.initialize', return_value=secrets, ) as mock_initialize: yield mock_initialize
def test_new_file(self): new_findings = secrets_collection_factory([ { 'filename': 'filename1', }, ]) baseline = secrets_collection_factory([ { 'filename': 'filename2', }, ]) backup_baseline = baseline.data.copy() results = get_secrets_not_in_baseline(new_findings, baseline) assert len(results.data) == 1 assert 'filename1' in results.data assert baseline.data == backup_baseline
def test_success_single_plugin(self): logic = secrets_collection_factory( plugins=(MockPluginFixedValue(),), ) with mock_open('junk text here, as it does not matter'): assert logic.scan_file('filename') assert 'filename' in logic.data assert next(iter(logic.data['filename'])).type == 'mock fixed value type'
def test_success_single_plugin(self): logic = secrets_collection_factory( plugins=(MockPluginFixedValue(), ), ) with mock_open('junk text here, as it does not matter'): assert logic.scan_file('filename') assert 'filename' in logic.data assert next(iter( logic.data['filename'])).type == 'mock fixed value type'
def test_new_file(self): new_findings = secrets_collection_factory([ { 'filename': 'filename1', }, ]) baseline = secrets_collection_factory([ { 'filename': 'filename2', }, ]) backup_baseline = baseline.data.copy() results = get_secrets_not_in_baseline(new_findings, baseline) assert len(results.data) == 1 assert 'filename1' in results.data assert baseline.data == backup_baseline
def test_file_is_symbolic_link(self): logic = secrets_collection_factory() with mock.patch( 'detect_secrets.core.secrets_collection.os.path', autospec=True, ) as mock_path: mock_path.islink.return_value = True assert not logic.scan_file('does_not_matter')
def test_explicit_type_for_optimization(self, type_, is_none): with self._mock_secret_hash(): logic = secrets_collection_factory(secrets=[ { 'filename': 'filename', 'type_': 'type', }, ]) assert (logic.get_secret('filename', 'secret_hash', type_) is None) == is_none
def test_file_is_symbolic_link(self): logic = secrets_collection_factory() with mock.patch( 'detect_secrets.core.secrets_collection.os.path', autospec=True, ) as mock_path: mock_path.islink.return_value = True assert not logic.scan_file('does_not_matter')
def test_explicit_type_for_optimization(self, type_, is_none): with self._mock_secret_hash(): logic = secrets_collection_factory(secrets=[ { 'filename': 'filename', 'type_': 'type', }, ]) assert (logic.get_secret('filename', 'secret_hash', type_) is None) == is_none
def test_deleted_secret_file(self): new_findings = secrets_collection_factory() baseline = secrets_collection_factory([ { 'filename': 'filename', }, ]) is_successful = update_baseline_with_removed_secrets( new_findings, baseline, [ # This is in baseline, but not in results, so # it should be deleted from baseline. 'filename', ], ) assert is_successful assert len(baseline.data) == 0
def load_from_diff(self, existing_secrets=None, baseline_filename='', exclude_regex=''): collection = secrets_collection_factory( secrets=existing_secrets, plugins=(HexHighEntropyString(3),), exclude_regex=exclude_regex, ) with open('test_data/sample.diff') as f: collection.scan_diff(f.read(), baseline_filename=baseline_filename) return collection
def load_from_diff(self, existing_secrets=None, baseline_filename='', exclude_regex=''): collection = secrets_collection_factory( secrets=existing_secrets, plugins=(HexHighEntropyString(3),), exclude_regex=exclude_regex, ) with open('test_data/sample.diff') as f: collection.scan_diff(f.read(), baseline_filename=baseline_filename) return collection
def test_deleted_secret_file(self): new_findings = secrets_collection_factory() baseline = secrets_collection_factory([ { 'filename': 'filename', }, ]) is_successful = trim_baseline_of_removed_secrets( new_findings, baseline, [ # This is in baseline, but not in results, so # it should be deleted from baseline. 'filename', ], ) assert is_successful assert len(baseline.data) == 0
def test_same_secret_new_location(self): new_findings = secrets_collection_factory([ { 'lineno': 1, }, ]) baseline = secrets_collection_factory([ { 'lineno': 2, }, ]) is_successful = update_baseline_with_removed_secrets( new_findings, baseline, ['filename'], ) assert is_successful assert len(baseline.data) == 1 assert next(iter(baseline.data['filename'])).lineno == 1
def test_unicode_decode_error(self, mock_log): logic = secrets_collection_factory(plugins=(MockPluginFileValue(), ), ) with mock_open('junk text here') as m: m().read.side_effect = MockUnicodeDecodeError logic.scan_file('filename') assert mock_log.getLogger().warning.called # If the file read was successful, secret would have been caught and added. assert len(logic.data) == 0
def test_unicode_decode_error(self, mock_log): logic = secrets_collection_factory(plugins=(MockPluginFileValue(), ), ) with mock_open('junk text here') as m: m().read.side_effect = MockUnicodeDecodeError logic.scan_file('filename') assert mock_log.info_messages == 'Checking file: filename\n' assert mock_log.warning_messages == 'filename failed to load.\n' # If the file read was successful, secret would have been caught and added. assert len(logic.data) == 0
def test_rolled_creds(self): """Same line, different secret""" new_findings = secrets_collection_factory([ { 'secret': 'secret_new', }, ]) baseline = secrets_collection_factory([ { 'secret': 'secret', }, ]) backup_baseline = baseline.data.copy() results = get_secrets_not_in_baseline(new_findings, baseline) assert len(results.data['filename']) == 1 secretA = PotentialSecret('type', 'filename', 'secret_new', 1) assert results.data['filename'][secretA].secret_hash == \ PotentialSecret.hash_secret('secret_new') assert baseline.data == backup_baseline
def test_rolled_creds(self): """Same line, different secret""" new_findings = secrets_collection_factory([ { 'secret': 'secret_new', }, ]) baseline = secrets_collection_factory([ { 'secret': 'secret', }, ]) backup_baseline = baseline.data.copy() results = get_secrets_not_in_baseline(new_findings, baseline) assert len(results.data['filename']) == 1 secretA = PotentialSecret('type', 'filename', 1, 'secret_new') assert results.data['filename'][secretA].secret_hash == \ PotentialSecret.hash_secret('secret_new') assert baseline.data == backup_baseline
def test_new_secret_line_old_file(self): """Same file, new line with potential secret""" new_findings = secrets_collection_factory([ { 'secret': 'secret1', 'lineno': 1, }, ]) baseline = secrets_collection_factory([ { 'secret': 'secret2', 'lineno': 2, }, ]) backup_baseline = baseline.data.copy() results = get_secrets_not_in_baseline(new_findings, baseline) assert len(results.data['filename']) == 1 secretA = PotentialSecret('type', 'filename', 'secret1', 1) assert results.data['filename'][secretA].secret_hash == \ PotentialSecret.hash_secret('secret1') assert baseline.data == backup_baseline
def test_new_secret_line_old_file(self): """Same file, new line with potential secret""" new_findings = secrets_collection_factory([ { 'secret': 'secret1', 'lineno': 1, }, ]) baseline = secrets_collection_factory([ { 'secret': 'secret2', 'lineno': 2, }, ]) backup_baseline = baseline.data.copy() results = get_secrets_not_in_baseline(new_findings, baseline) assert len(results.data['filename']) == 1 secretA = PotentialSecret('type', 'filename', 1, 'secret1') assert results.data['filename'][secretA].secret_hash == \ PotentialSecret.hash_secret('secret1') assert baseline.data == backup_baseline
def test_optional_type(self, filename, secret_hash, expected_value): with self._mock_secret_hash(): logic = secrets_collection_factory([ { 'filename': 'filename', 'lineno': 1, }, ]) result = logic.get_secret(filename, secret_hash) if expected_value: assert result assert result.lineno == 1 # make sure lineno is the same else: assert not result
def test_optional_type(self, filename, secret_hash, expected_value): with self._mock_secret_hash(): logic = secrets_collection_factory([ { 'filename': 'filename', 'lineno': 1, }, ]) result = logic.get_secret(filename, secret_hash) if expected_value: assert result assert result.lineno == 1 # make sure lineno is the same else: assert not result
def test_unicode_decode_error(self, mock_log): logic = secrets_collection_factory( plugins=(MockPluginFileValue(),), ) with mock_open('junk text here') as m: m().read.side_effect = MockUnicodeDecodeError logic.scan_file('filename') assert mock_log.info_messages == 'Checking file: filename\n' assert mock_log.warning_messages == 'filename failed to load.\n' # If the file read was successful, secret would have been caught and added. assert len(logic.data) == 0
def test_get_secrets_from_baseline(self, use_default_filter_func): baseline = secrets_collection_factory([ { 'filename': 'filename1', }, ]) backup_baseline = baseline.data.copy() if use_default_filter_func: results = get_secrets_from_baseline(baseline) else: results = get_secrets_from_baseline(baseline, filter_func=None) assert len(results.data) == 1 assert 'filename1' in results.data assert baseline.data == backup_baseline
def test_always_writes_state_with_always_update_state_flag( self, mock_file_operations, ): secrets = secrets_collection_factory([ { 'filename': 'file_with_secrets', 'lineno': 5, }, ]) with self.setup_env( secrets, '--always-update-state', updates_repo=True, ) as args: assert scan_repo(args) == 0 assert mock_file_operations.write.called
def test_scan_head_and_does_not_write_state_when_scan_head( self, mock_file_operations, mock_logger, ): secrets = secrets_collection_factory([ { 'filename': 'file_with_secrets', 'lineno': 5, }, ]) with self.setup_env( secrets, '--scan-head', ) as args: secret_hash = list( secrets.data['file_with_secrets'].values() )[0].secret_hash args.output_hook = mock_external_hook( 'yelp/detect-secrets', { 'file_with_secrets': [{ 'type': 'type', 'hashed_secret': secret_hash, 'is_verified': False, 'line_number': 5, 'author': 'khock', 'commit': 'new_sha', }], }, ) assert scan_repo(args) == 0 mock_logger.error.assert_called_with( 'Secrets found in %s', 'yelp/detect-secrets', ) assert not mock_file_operations.write.called
def test_reporting_of_password_plugin_secrets_if_reported_already(self): logic = secrets_collection_factory( secrets=[ { 'filename': 'filename', 'lineno': 3, }, ], plugins=( MockPasswordPluginValue(), MockPluginFileValue(), ), ) with mock_open('junk text here'): logic.scan_file('filename') assert len(logic.data['filename']) == 3 line_numbers = [entry.lineno for entry in logic.data['filename']] assert set(line_numbers) == set([2, 3])
def test_success_multiple_plugins(self): logic = secrets_collection_factory( secrets=[ { 'filename': 'filename', 'lineno': 3, }, ], plugins=( MockPluginFixedValue(), MockPluginFileValue(), ), ) with mock_open('junk text here'): logic.scan_file('filename') # One from each plugin, and one from existing secret assert len(logic.data['filename']) == 3 line_numbers = [entry.lineno for entry in logic.data['filename']] assert set(line_numbers) == set([1, 2, 3])
def test_success_multiple_plugins(self): logic = secrets_collection_factory( secrets=[ { 'filename': 'filename', 'lineno': 3, }, ], plugins=( MockPluginFixedValue(), MockPluginFileValue(), ), ) with mock_open('junk text here'): logic.scan_file('filename') # One from each plugin, and one from existing secret assert len(logic.data['filename']) == 3 line_numbers = [entry.lineno for entry in logic.data['filename']] assert set(line_numbers) == set([1, 2, 3])
def test_alerts_on_secrets_found( self, mock_file_operations, mock_logger, ): secrets = secrets_collection_factory([ { 'filename': 'file_with_secrets', 'lineno': 5, }, ]) with self.setup_env(secrets) as args: secret_hash = list( secrets.data['file_with_secrets'].values())[0].secret_hash args.output_hook = mock_external_hook( 'yelp/detect-secrets', { 'file_with_secrets': [{ 'type': 'type', 'hashed_secret': secret_hash, 'line_number': 5, 'author': 'khock', 'commit': 'd39c008353447bbc1845812fcaf0a03b50af439f', }], }, ) assert scan_repo(args) == 0 mock_logger.error.assert_called_with( 'Secrets found in %s', 'yelp/detect-secrets', ) assert not mock_file_operations.write.called
def setup(self): self.logic = secrets_collection_factory( secrets=[ { 'type_': 'A', 'lineno': 3, 'filename': 'fileA', }, { 'type_': 'B', 'lineno': 2, 'filename': 'fileA', }, { 'type_': 'C', 'lineno': 1, 'filename': 'fileB', }, ], plugins=( HexHighEntropyString(3), PrivateKeyDetector(), ), )
def mock_initialize_function(plugins, exclude_regex, *args, **kwargs): return secrets_collection_factory( plugins=plugins, exclude_regex=exclude_regex, )
def test_ignore_baseline_file(self, mock_get_baseline): mock_get_baseline.return_value = secrets_collection_factory() assert_commit_blocked('test_data/baseline.file') assert_commit_succeeds('--baseline baseline.file baseline.file')
def test_error_reading_file(self, mock_log): logic = secrets_collection_factory() assert not logic.scan_file('non_existent_file') mock_log.warning_messages == 'Unable to open file: non_existent_file'
def test_ignore_baseline_file(self, mock_get_baseline): mock_get_baseline.return_value = secrets_collection_factory() assert_commit_blocked('--use-all-plugins test_data/baseline.file') assert_commit_succeeds( '--use-all-plugins --baseline baseline.file baseline.file')
def test_error_reading_file(self, mock_log): logic = secrets_collection_factory() assert not logic.scan_file('non_existent_file') mock_log.getLogger().warning.assert_called_once()
def test_error_reading_file(self, mock_log): logic = secrets_collection_factory() assert not logic.scan_file('non_existent_file') mock_log.warning_messages == 'Unable to open file: non_existent_file'