Skip to content

Commit

Permalink
feat: Read plugins list from baseline
Browse files Browse the repository at this point in the history
  • Loading branch information
Xianjun Zhu committed Feb 5, 2019
1 parent a3d30c8 commit 9e0b619
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 18 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
/.coverage
/.pytest_cache
/.tox
/venv**
/venv*
/tmp

.*ignore
!.gitignore
.python-version
.vscode
4 changes: 2 additions & 2 deletions detect_secrets/core/secrets_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ def load_baseline_from_string(cls, string):
:raises: IOError
"""
try:
return cls._load_baseline_from_dict(json.loads(string))
return cls.load_baseline_from_dict(json.loads(string))
except (IOError, ValueError):
log.error('Incorrectly formatted baseline!')
raise

@classmethod
def _load_baseline_from_dict(cls, data):
def load_baseline_from_dict(cls, data):
"""Initializes a SecretsCollection object from dictionary.
:type data: dict
Expand Down
24 changes: 22 additions & 2 deletions detect_secrets/core/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
from detect_secrets import VERSION


def add_use_all_plugins_argument(parser):
parser.add_argument(
'--use-all-plugins',
action='store_true',
help='Use all available plugins to scan files',
)


class ParserBuilder(object):

def __init__(self):
Expand All @@ -21,7 +29,8 @@ def add_default_arguments(self):

def add_pre_commit_arguments(self):
self._add_filenames_argument()\
._add_set_baseline_argument()
._add_set_baseline_argument()\
._add_use_all_plugins_argument()

PluginOptions(self.parser).add_arguments()

Expand Down Expand Up @@ -78,6 +87,9 @@ def _add_set_baseline_argument(self):
)
return self

def _add_use_all_plugins_argument(self):
add_use_all_plugins_argument(self.parser)


class ScanOptions(object):

Expand Down Expand Up @@ -122,6 +134,9 @@ def _add_initialize_baseline_argument(self):
dest='import_filename',
)

# Pairing `--update` with `--use-all-plugins` to overwrite plugins list from baseline
add_use_all_plugins_argument(self.parser)

self.parser.add_argument(
'--all-files',
action='store_true',
Expand Down Expand Up @@ -293,16 +308,20 @@ def consolidate_args(args):
return

active_plugins = {}
disabled_plugins = {}

for plugin in PluginOptions.all_plugins:
arg_name = PluginOptions._convert_flag_text_to_argument_name(
plugin.disable_flag_text,
)

# Remove disabled plugins
is_disabled = getattr(args, arg_name)
is_disabled = getattr(args, arg_name, False)
delattr(args, arg_name)
if is_disabled:
disabled_plugins.update({
plugin.classname: {},
})
continue

# Consolidate related args
Expand All @@ -329,6 +348,7 @@ def consolidate_args(args):
})

args.plugins = active_plugins
args.disabled_plugins = disabled_plugins

def _add_custom_limits(self):
high_entropy_help_text = (
Expand Down
20 changes: 16 additions & 4 deletions detect_secrets/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from detect_secrets.core import baseline
from detect_secrets.core.common import write_baseline_to_file
from detect_secrets.core.log import log
from detect_secrets.core.secrets_collection import SecretsCollection
from detect_secrets.core.usage import ParserBuilder
from detect_secrets.plugins.common import initialize

Expand Down Expand Up @@ -39,10 +40,12 @@ def main(argv=None):
_scan_string(line, plugins)

else:
baseline_dict = _perform_scan(
args,
plugins,
)
if args.import_filename:
plugins = initialize.merge_plugin_from_baseline(
_get_plugin_from_baseline(args.import_filename), args,
)

baseline_dict = _perform_scan(args, plugins)

if args.import_filename:
write_baseline_to_file(
Expand Down Expand Up @@ -79,6 +82,15 @@ def main(argv=None):
return 0


def _get_plugin_from_baseline(baseline_file):
old_baseline = _get_existing_baseline(baseline_file)
plugins = []
if old_baseline and "plugins_used" in old_baseline:
secrets_collection = SecretsCollection.load_baseline_from_dict(old_baseline)
plugins = secrets_collection.plugins
return plugins


def _scan_string(line, plugins):
longest_plugin_name_length = max(
map(
Expand Down
25 changes: 25 additions & 0 deletions detect_secrets/plugins/common/initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ def from_parser_builder(plugins_dict):
return tuple(output)


def merge_plugin_from_baseline(baseline_plugins, args):
# if --use-all-plugins
# include all parsed plugins
# else
# include all baseline plugins
# remove all disabled plugins

plugins = []
if args.use_all_plugins:
plugins = from_parser_builder(args.plugins)
elif args.disabled_plugins: # strip some plugins off baseline
plugins = _merge_plugin_from_baseline(baseline_plugins, args)
else:
plugins = baseline_plugins
return plugins


def _merge_plugin_from_baseline(baseline_plugins, args):
merged_plugins_dict = {vars(plugin)['name']: plugin for plugin in baseline_plugins}
for plugin_name in args.disabled_plugins:
if plugin_name in merged_plugins_dict:
merged_plugins_dict.pop(plugin_name)
return merged_plugins_dict.values()


def from_plugin_classname(plugin_classname, **kwargs):
"""Initializes a plugin class, given a classname and kwargs.
Expand Down
7 changes: 6 additions & 1 deletion detect_secrets/pre_commit_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ def main(argv=None):
return 1

plugins = initialize.from_parser_builder(args.plugins)

# Merge plugin from baseline
if baseline_collection:
plugins = initialize.merge_plugin_from_baseline(baseline_collection.plugins, args)
baseline_collection.plugins = plugins

results = find_secrets_in_files(args, plugins)
if baseline_collection:
original_results = results
Expand All @@ -59,7 +65,6 @@ def main(argv=None):
)

if VERSION != baseline_collection.version:
baseline_collection.plugins = plugins
baseline_collection.version = VERSION
baseline_modified = True

Expand Down
24 changes: 24 additions & 0 deletions tests/core/baseline_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,30 @@ def test_new_results_has_nothing(self):

assert merge_results(old_result, {}) == {}

def test_old_results_have_diff_type_will_carry_over(self):
secretA = self.get_secret()
secretA["type"] = "different type"
secretB = self.get_secret()

assert merge_results(
{
'filenameA': [
secretA,
],
},
{
'filenameA': [
secretA,
secretB,
],
},
) == {
'filenameA': [
secretA,
secretB,
],
}

def test_old_results_have_subset_of_new_results(self):
secretA = self.get_secret()
secretB = self.get_secret()
Expand Down
2 changes: 1 addition & 1 deletion tests/core/secrets_collection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def test_output(self, mock_gmtime):

def test_load_baseline_from_string(self, mock_gmtime):
"""
We use load_baseline_from_string as a proxy to testing _load_baseline_from_dict,
We use load_baseline_from_string as a proxy to testing load_baseline_from_dict,
because it's the most entry into the private function.
"""
original = self.get_baseline_dict(mock_gmtime)
Expand Down
Loading

0 comments on commit 9e0b619

Please sign in to comment.