Exemple #1
0
def get_plugin_report(extra=None):
    """
    :type extra: Dict[str, str]
    """
    if not extra:  # pragma: no cover
        extra = {}

    longest_name_length = max([len(name) for name in import_plugins()])

    return '\n'.join(
        sorted([
            '{name}: {result}'.format(
                name=name + ' ' * (longest_name_length - len(name)),
                result='False' if name not in extra else extra[name],
            ) for name in import_plugins()
        ]), ) + '\n'
Exemple #2
0
def get_list_of_plugins(include=None, exclude=None):
    """
    :type include: List[Dict[str, Any]]
    :type exclude: Iterable[str]
    :rtype: List[Dict[str, Any]]
    """
    included_plugins = []
    if include:
        included_plugins = [config['name'] for config in include]

    output = []
    for name, plugin in import_plugins().items():
        if (name in included_plugins or exclude and name in exclude):
            continue

        payload = {
            'name': name,
        }
        payload.update(plugin.default_options)

        output.append(payload)

    if include:
        output.extend(include)

    return sorted(output, key=lambda x: x['name'])
    def test_consolidates_output_basic(self):
        """Everything enabled by default, with default values"""
        args = self.parse_args()

        regex_based_plugins = {key: {} for key in import_plugins()}
        regex_based_plugins.update({
            'HexHighEntropyString': {
                'hex_limit': 3,
            },
            'Base64HighEntropyString': {
                'base64_limit': 4.5,
            },
            'KeywordDetector': {
                'keyword_exclude': None,
            },
        })
        assert not hasattr(args, 'no_private_key_scan')
Exemple #4
0
def from_plugin_classname(plugin_classname,
                          custom_plugin_paths,
                          exclude_lines_regex=None,
                          automaton=None,
                          should_verify_secrets=False,
                          **kwargs):
    """Initializes a plugin class, given a classname and kwargs.

    :type plugin_classname: str
    :param plugin_classname: subclass of BasePlugin.

    :type custom_plugin_paths: Tuple[str]
    :param custom_plugin_paths: possibly empty tuple of paths that have custom plugins.

    :type exclude_lines_regex: str|None
    :param exclude_lines_regex: optional regex for ignored lines.

    :type automaton: ahocorasick.Automaton|None
    :param automaton: optional automaton for ignoring English-words.

    :type should_verify_secrets: bool
    """
    try:
        klass = import_plugins(custom_plugin_paths)[plugin_classname]
    except KeyError:
        log.error('Error: No such `{}` plugin to initialize.'.format(
            plugin_classname))
        log.error('Chances are you should run `pre-commit autoupdate`.')
        log.error(
            'This error can occur when using a baseline that was made by '
            'a newer detect-secrets version than the one running.', )
        log.error(
            'It can also occur if the baseline has custom plugin paths, '
            'but the `--custom-plugins` option was not passed.', )
        raise TypeError

    try:
        instance = klass(exclude_lines_regex=exclude_lines_regex,
                         automaton=automaton,
                         should_verify=should_verify_secrets,
                         **kwargs)
    except TypeError:
        log.error('Unable to initialize plugin!')
        raise

    return instance
Exemple #5
0
def get_all_plugin_descriptors(custom_plugin_paths):
    return [
        PluginDescriptor.from_plugin_class(plugin, name)
        for name, plugin in import_plugins(custom_plugin_paths).items()
    ]
Exemple #6
0
class PluginOptions(object):

    all_plugins = [
        PluginDescriptor.from_plugin_class(plugin, name)
        for name, plugin in import_plugins().items()
    ]

    def __init__(self, parser):
        self.parser = parser.add_argument_group(
            title='plugins',
            description=('Configure settings for each secret scanning '
                         'ruleset. By default, all plugins are enabled '
                         'unless explicitly disabled.'),
        )

    def add_arguments(self):
        self._add_custom_limits()
        self._add_opt_out_options()
        self._add_keyword_exclude()

        return self

    @staticmethod
    def get_disabled_plugins(args):
        return [
            plugin.classname for plugin in PluginOptions.all_plugins
            if plugin.classname not in args.plugins
        ]

    @staticmethod
    def consolidate_args(args):
        """There are many argument fields related to configuring plugins.
        This function consolidates all of them, and saves the consolidated
        information in args.plugins.

        Note that we're deferring initialization of those plugins, because
        plugins may have various initialization values, referenced in
        different places.

        :param args: output of `argparse.ArgumentParser.parse_args`
        """
        # Using `--hex-limit` as a canary to identify whether this
        # consolidation is appropriate.
        if not hasattr(args, 'hex_limit'):
            return

        active_plugins = {}
        is_using_default_value = {}

        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, False)
            delattr(args, arg_name)
            if is_disabled:
                continue

            # Consolidate related args
            related_args = {}
            for related_arg_tuple in plugin.related_args:
                flag_name, default_value = related_arg_tuple

                arg_name = PluginOptions._convert_flag_text_to_argument_name(
                    flag_name, )

                related_args[arg_name] = getattr(args, arg_name)
                delattr(args, arg_name)

                if default_value and related_args[arg_name] is None:
                    related_args[arg_name] = default_value
                    is_using_default_value[arg_name] = True

            active_plugins.update({
                plugin.classname: related_args,
            })

        args.plugins = active_plugins
        args.is_using_default_value = is_using_default_value

    def _add_custom_limits(self):
        high_entropy_help_text = (
            'Sets the entropy limit for high entropy strings. '
            'Value must be between 0.0 and 8.0, ')

        self.parser.add_argument(
            '--base64-limit',
            type=self._argparse_minmax_type,
            nargs='?',
            help=high_entropy_help_text + 'defaults to 4.5.',
        )
        self.parser.add_argument(
            '--hex-limit',
            type=self._argparse_minmax_type,
            nargs='?',
            help=high_entropy_help_text + 'defaults to 3.0.',
        )

    def _add_opt_out_options(self):
        for plugin in self.all_plugins:
            self.parser.add_argument(
                plugin.disable_flag_text,
                action='store_true',
                help=plugin.disable_help_text,
                default=False,
            )

    def _argparse_minmax_type(self, string):
        """Custom type for argparse to enforce value limits"""
        value = float(string)
        if value < 0 or value > 8:
            raise argparse.ArgumentTypeError(
                '%s must be between 0.0 and 8.0' % string, )

        return value

    @staticmethod
    def _convert_flag_text_to_argument_name(flag_text):
        """This just emulates argparse's underlying logic.

        :type flag_text: str
        :param flag_text: e.g. `--no-hex-string-scan`
        :return: `no_hex_string_scan`
        """
        return flag_text[2:].replace('-', '_')

    def _add_keyword_exclude(self):
        self.parser.add_argument(
            '--keyword-exclude',
            type=str,
            help=
            'Pass in regex to exclude false positives found by keyword detector.',
        )
Exemple #7
0
def get_regex_based_plugins():
    return {
        name: plugin
        for name, plugin in import_plugins(custom_plugin_paths=()).items()
        if issubclass(plugin, RegexBasedDetector)
    }