def test_fails_on_bad_initialization(self): with mock.patch.object( HexHighEntropyString, '__init__', side_effect=TypeError, ), pytest.raises(TypeError, ): initialize.from_plugin_classname( 'HexHighEntropyString', hex_limit=4, )
def test_fails_on_bad_initialization(self): with mock.patch( 'detect_secrets.plugins.common.initialize.import_plugins', # Trying to instantiate str() like a plugin throws TypeError return_value={'HexHighEntropyString': str}, ), pytest.raises( TypeError, ): initialize.from_plugin_classname( plugin_classname='HexHighEntropyString', custom_plugin_paths=(), hex_limit=4, )
def test_success(self): plugin = initialize.from_plugin_classname( 'HexHighEntropyString', hex_limit=4, ) assert isinstance(plugin, HexHighEntropyString) assert plugin.entropy_limit == 4
def load_baseline_from_dict(cls, data): """Initializes a SecretsCollection object from dictionary. :type data: dict :param data: properly formatted dictionary to load SecretsCollection from. :rtype: SecretsCollection :raises: IOError """ result = SecretsCollection() if not all(key in data for key in ( 'plugins_used', 'results', )): raise IOError # In v0.12.0 `exclude_regex` got replaced by `exclude` if not any(key in data for key in ( 'exclude', 'exclude_regex', )): raise IOError if 'exclude_regex' in data: result.exclude_files = data['exclude_regex'] else: result.exclude_files = data['exclude']['files'] result.exclude_lines = data['exclude']['lines'] plugins = [] for plugin in data['plugins_used']: plugin_classname = plugin.pop('name') plugins.append( initialize.from_plugin_classname( plugin_classname, exclude_lines_regex=result.exclude_lines, should_verify_secrets=False, **plugin), ) result.plugins = tuple(plugins) for filename in data['results']: result.data[filename] = {} for item in data['results'][filename]: secret = PotentialSecret( item['type'], filename, secret='will be replaced', lineno=item['line_number'], is_secret=item.get('is_secret'), ) secret.secret_hash = item['hashed_secret'] result.data[filename][secret] = secret result.version = (data['version'] if 'version' in data else '0.0.0') return result
def test_success(self): plugin = initialize.from_plugin_classname( plugin_classname='HexHighEntropyString', custom_plugin_paths=(), hex_limit=4, ) # Dynamically imported classes have different # addresses for the same functions as statically # imported classes do, so isinstance does not work. assert str(plugin.__class__) == str(HexHighEntropyString) assert dir(plugin.__class__) == dir(HexHighEntropyString) assert plugin.entropy_limit == 4
def load_baseline_from_dict(cls, data, plugin_filenames=None): """Initializes a SecretsCollection object from dictionary. :type data: dict :param data: properly formatted dictionary to load SecretsCollection from. :type plugin_filenames: tuple :param plugin_filenames: the plugin filenames. :rtype: SecretsCollection :raises: IOError """ result = SecretsCollection() if not all(key in data for key in ( 'plugins_used', 'results', )): raise IOError # In v0.12.0 `exclude_regex` got replaced by `exclude` if not any(key in data for key in ( 'exclude', 'exclude_regex', )): raise IOError if 'exclude_regex' in data: result.exclude_files = data['exclude_regex'] else: result.exclude_files = data['exclude']['files'] result.exclude_lines = data['exclude']['lines'] # In v0.12.7 the `--word-list` option got added automaton = None if 'word_list' in data: result.word_list_file = data['word_list']['file'] result.word_list_hash = data['word_list']['hash'] if result.word_list_file: # Always ignore the given `data['word_list']['hash']` # The difference will show whenever the word list changes automaton, result.word_list_hash = build_automaton( result.word_list_file) plugins = [] for plugin in data['plugins_used']: plugin_classname = plugin.pop('name') initialized_plugin_classname = initialize.from_plugin_classname( plugin_classname, exclude_lines_regex=result.exclude_lines, automaton=automaton, should_verify_secrets=True, plugin_filenames=plugin_filenames, **plugin, ) if initialized_plugin_classname is not None: plugins.append(initialized_plugin_classname) result.plugins = tuple(plugins) for filename in data['results']: result.data[filename] = {} for item in data['results'][filename]: secret = PotentialSecret( item['type'], filename, secret='will be replaced', lineno=item['line_number'], is_secret=item.get('is_secret'), output_raw=result.output_raw, is_verified=item['is_verified'], verified_result=item.get('verified_result'), ) secret.secret_hash = item['hashed_secret'] result.data[filename][secret] = secret result.version = (data['version'] if 'version' in data else '0.0.0') return result
def load_baseline_from_dict(cls, data): """Initializes a SecretsCollection object from dictionary. :type data: dict :param data: properly formatted dictionary to load SecretsCollection from. :rtype: SecretsCollection :raises: IOError """ result = SecretsCollection() if not all(key in data for key in ( 'plugins_used', 'results', )): raise IOError # In v0.12.0 `exclude_regex` got replaced by `exclude` if not any(key in data for key in ( 'exclude', 'exclude_regex', )): raise IOError if 'exclude_regex' in data: result.exclude_files = data['exclude_regex'] else: result.exclude_files = data['exclude']['files'] result.exclude_lines = data['exclude']['lines'] # In v0.12.7 the `--word-list` option got added automaton = None if 'word_list' in data: result.word_list_file = data['word_list']['file'] result.word_list_hash = data['word_list']['hash'] if result.word_list_file: # Always ignore the existing `data['word_list']['hash']` # The difference will show whenever the word list changes automaton, result.word_list_hash = build_automaton( result.word_list_file) # In v0.14.0 the `--custom-plugins` option got added result.custom_plugin_paths = tuple(data.get('custom_plugin_paths', ())) result.plugins = tuple( initialize.from_plugin_classname( plugin_classname=plugin.pop('name'), custom_plugin_paths=result.custom_plugin_paths, exclude_lines_regex=result.exclude_lines, automaton=automaton, should_verify_secrets=False, **plugin) for plugin in data['plugins_used']) for filename in data['results']: result.data[filename] = {} for item in data['results'][filename]: secret = PotentialSecret( item['type'], filename, secret='will be replaced', lineno=item['line_number'], is_secret=item.get('is_secret'), ) secret.secret_hash = item['hashed_secret'] result.data[filename][secret] = secret result.version = (data['version'] if 'version' in data else '0.0.0') return result
def test_return_none_if_not_base_plugin(self): plugin = initialize.from_plugin_classname('log', ) assert not plugin
def test_fails_if_not_base_plugin(self): with pytest.raises(TypeError): initialize.from_plugin_classname( 'log', )
def test_fails_if_not_base_plugin(self): with pytest.raises(TypeError): initialize.from_plugin_classname( plugin_classname='NotABasePlugin', custom_plugin_paths=(), )
from detect_secrets.core.secrets_collection import SecretsCollection from detect_secrets.core.potential_secret import PotentialSecret from detect_secrets.plugins.common.initialize import from_plugin_classname from .base import Tool, Issue, AccessIssue, UnknownIssue class DetectSecretsIssue(Issue): tool = 'secrets' pylint_type = 'W' PLUGINS = [ from_plugin_classname( _plugin.classname, (), **dict([( _arg[0][2:].replace('-', '_'), _arg[1], ) for _arg in _plugin.related_args])) for _plugin in get_all_plugin_descriptors(()) ] DESCRIPTION = 'Possible secret detected: {description}' def plugin_code(plugin): return plugin.__class__.__name__ class DetectSecretsTool(Tool): """ The secrets tool attempts to detect secrets (keys, passwords, etc) that are