Making Bandit into an installable package and adding tox tests

This large change makes bandit into an installable packahge, needed
for tox testing. I have added the tox testing scaffolding but no
real tests, they will come in a later change. I have also disabled
all failing PEP8 test (lots) since I have changed enough stuff for
one patch. I'll start re-enabling and fixing PEP8 stuff soon.

Change-Id: I774ed9149f285e4e2bceacda0484a7e2a934a3aa
This commit is contained in:
Tim Kelsey 2014-10-21 14:11:22 +01:00
parent af1ec3dacb
commit 8e6697b063
36 changed files with 204 additions and 27 deletions

5
.gitignore vendored
View File

@ -1,2 +1,7 @@
*.pyc
.DS_Store
*.egg
*.egg-info
.tox
.testrepository
build/*

7
.testr.conf Normal file
View File

@ -0,0 +1,7 @@
[DEFAULT]
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

@ -14,14 +14,14 @@
#    License for the specific language governing permissions and limitations
#    under the License.
import config
import context
import manager
import meta_ast
import node_visitor
import result_store
import test_set
import tester
import utils
from constants import *
from test_selector import *
from core import config
from core import context
from core import manager
from core import meta_ast
from core import node_visitor
from core import result_store
from core import test_set
from core import tester
from core import utils
from core.constants import *
from core.test_selector import *

View File

@ -16,11 +16,11 @@
#    under the License.
import argparse
from bandit import manager as b_manager
from core import manager as b_manager
default_test_config = 'bandit.yaml'
if __name__ == '__main__':
def main():
parser = argparse.ArgumentParser(
description='Bandit - a Python source code analyzer.'
)
@ -72,3 +72,6 @@ if __name__ == '__main__':
if args.debug:
b_mgr.output_metaast()
b_mgr.output_results(args.context_lines, args.level - 1, args.output_file)
if __name__ == '__main__':
main()

27
bandit/core/__init__.py Normal file
View File

@ -0,0 +1,27 @@
# -*- coding:utf-8 -*-
#
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
#    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.
import config
import context
import manager
import meta_ast
import node_visitor
import result_store
import test_set
import tester
import utils
from constants import *
from test_selector import *

View File

@ -14,6 +14,9 @@
#    License for the specific language governing permissions and limitations
#    under the License.
import os
from distutils.sysconfig import get_python_lib
# default output text colors
color = {
'DEFAULT': '\033[0m',
@ -30,7 +33,7 @@ plugin_name_pattern = '*.py'
progress_increment = 50
# default plugins dir
plugins_dir = 'plugins'
plugins_dir = os.path.join(get_python_lib(), 'bandit', 'plugins')
# flag/s used to mark lines where identified issues should not be reported
SKIP_FLAGS = ['nosec', ]

View File

@ -15,7 +15,7 @@
#    under the License.
import _ast
from bandit import utils
import utils
class Context():

View File

@ -18,11 +18,11 @@
import sys
import logging
import ast
from bandit import config as b_config
from bandit import result_store as b_result_store
from bandit import node_visitor as b_node_visitor
from bandit import test_set as b_test_set
from bandit import meta_ast as b_meta_ast
import config as b_config
import result_store as b_result_store
import node_visitor as b_node_visitor
import test_set as b_test_set
import meta_ast as b_meta_ast
class BanditManager():

View File

@ -19,8 +19,8 @@ import sys
import ast
import _ast
import copy
from bandit import tester as b_tester
from bandit import utils as b_utils
import tester as b_tester
import utils as b_utils
class BanditNodeVisitor(ast.NodeVisitor):

View File

@ -16,6 +16,7 @@
import copy
import os
import sys
from collections import OrderedDict
import glob
@ -105,7 +106,7 @@ class BanditTestSet():
# we need to know the name of the decorators so we can automatically
# ignore them when discovering functions
decorator_source_file = "bandit.test_selector"
decorator_source_file = "bandit.core.test_selector"
module = importlib.import_module(decorator_source_file)
return_list = []
@ -131,12 +132,16 @@ class BanditTestSet():
decorators = self._get_decorators_list()
# try to import each python file in the plugins directory
sys.path.append(os.path.dirname(directory))
for file in glob.glob1(directory, plugin_name_pattern):
module_name = file.split('.')[0]
module_name = os.path.basename(file).split('.')[0]
# try to import the module by name
try:
module = importlib.import_module(directory + '.' + module_name)
outer = os.path.basename(os.path.normpath(directory))
self.logger.debug("importing test: {0}".format(
outer + '.' + module_name))
module = importlib.import_module(outer + '.' + module_name)
# if it fails, die
except ImportError as e:
@ -191,8 +196,10 @@ class BanditTestSet():
:param checktype: The type of test to filter on
:return: A dictionary of tests which are of the specified type
'''
scoped_tests = {}
self.logger.debug('get_tests called with check type: %s' % checktype)
scoped_tests = self.tests[checktype]
if checktype in self.tests:
scoped_tests = self.tests[checktype]
self.logger.debug('get_tests returning scoped_tests : %s' %
scoped_tests)
return scoped_tests

View File

@ -15,7 +15,7 @@
#    under the License.
import bandit.context as b_context
import context as b_context
class BanditTester():

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
PyYAML>=3.1.0

22
scripts/main.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
#    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 bandit import bandit
if __name__ == '__main__':
bandit.main()

31
setup.cfg Normal file
View File

@ -0,0 +1,31 @@
[metadata]
name = bandit
summary = Security oriented static analyser for python code.
description-file =
README.md
author = OpenStack Security Group
author-email = openstack-security@lists.openstack.org
home-page = https://wiki.openstack.org/wiki/Security/Projects/Bandit
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
Intended Audience :: System Administrators
Intended Audience :: Developers
License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
Operating System :: MacOS :: MacOS X
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 2.6
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
Topic :: Security
[files]
packages =
bandit
[entry_points]
console_scripts =
bandit = bandit.bandit:main

22
setup.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# 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.
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
import setuptools
setuptools.setup(
setup_requires=['pbr'],
pbr=True)

8
test-requirements.txt Normal file
View File

@ -0,0 +1,8 @@
coverage>=3.6
discover
fixtures>=0.3.14
hacking>=0.9.2,<0.10
python-subunit>=0.0.18
testrepository>=0.0.18
testscenarios>=0.4
testtools>=0.9.34

40
tox.ini Normal file
View File

@ -0,0 +1,40 @@
[tox]
minversion = 1.6
envlist = py26,py27,py33,pypy,pep8
skipsdist = True
[testenv]
usedevelop = True
install_command = pip install -U {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = python setup.py testr --slowest --testr-args='{posargs}'
[testenv:pep8]
commands = flake8 {posargs} bandit
[testenv:venv]
commands = {posargs}
[testenv:cover]
commands = python setup.py testr --coverage --testr-args='{posargs}'
[flake8]
# E123, E125 skipped as they are invalid PEP-8.
# These tests are skipped for now, they will be added in later:
# H404 multi line docstring should start without a leading new line
# H405 multi line docstring summary not separated with an empty line
# H306 imports not in alphabetical order
# H301 one import per line
# H101 Use TODO(NAME)
# H103 Header does not match Apache 2.0 License notice
# H904 Wrap long lines in parentheses instead of a backslash
# E271 multiple spaces after keyword
# E301 expected 1 blank line, found 0
show-source = True
ignore = E123,E125,H404,H405,H306,H301,H101,H103,H904,E271,E301,
builtins = _
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build