bandit/bandit/core/extension_loader.py

86 lines
3.4 KiB
Python

# -*- coding:utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import sys
import six
from stevedore import extension
class Manager(object):
def __init__(self, formatters_namespace='bandit.formatters',
plugins_namespace='bandit.plugins',
blacklists_namespace='bandit.blacklists'):
# Cache the extension managers, loaded extensions, and extension names
self.load_formatters(formatters_namespace)
self.load_plugins(plugins_namespace)
self.load_blacklists(blacklists_namespace)
def load_formatters(self, formatters_namespace):
self.formatters_mgr = extension.ExtensionManager(
namespace=formatters_namespace,
# We don't want to call the formatter when we load it.
invoke_on_load=False,
# We don't care if the extension doesn't have the dependencies it
# needs to start up.
verify_requirements=False,
)
self.formatters = list(self.formatters_mgr)
self.formatter_names = self.formatters_mgr.names()
def load_plugins(self, plugins_namespace):
# See comments in load_formatters for parameter explanations
self.plugins_mgr = extension.ExtensionManager(
namespace=plugins_namespace,
invoke_on_load=False,
verify_requirements=False,
)
def test_has_id(plugin):
if not hasattr(plugin.plugin, "_test_id"):
# logger not setup yet, so using print
print("WARNING: Test '%s' has no ID, skipping." % plugin.name,
file=sys.stderr)
return False
return True
self.plugins = list(filter(test_has_id, list(self.plugins_mgr)))
self.plugin_names = [plugin.name for plugin in self.plugins]
self.plugins_by_id = {p.plugin._test_id: p for p in self.plugins}
self.plugin_name_to_id = {
p.name: p.plugin._test_id for p in self.plugins}
def get_plugin_id(self, plugin_name):
return self.plugin_name_to_id.get(plugin_name)
def load_blacklists(self, blacklist_namespace):
self.blacklists_mgr = extension.ExtensionManager(
namespace=blacklist_namespace,
invoke_on_load=False,
verify_requirements=False,
)
self.blacklist = {}
blacklist = list(self.blacklists_mgr)
for item in blacklist:
for key, val in six.iteritems(item.plugin()):
self.blacklist.setdefault(key, []).extend(val)
# Using entry-points and pkg_resources *can* be expensive. So let's load these
# once, store them on the object, and have a module global object for
# accessing them. After the first time this module is imported, it should save
# this attribute on the module and not have to reload the entry-points.
MANAGER = Manager()