From c89dff7994ee2e8a7a9cd2af3d1cb7a4cbb9c88e Mon Sep 17 00:00:00 2001 From: kevgliss Date: Mon, 20 Jul 2015 16:13:42 -0700 Subject: [PATCH 01/32] Getting travisCI setup --- .gitignore | 2 ++ .travis.yml | 32 +++++++++++++---- Makefile | 83 +++++++++++++++++++++++++++++++++++++++++++ docs/requirements.txt | 5 +++ gulp/build.js | 10 ++++++ gulp/karma.conf.js | 27 ++++++++++++++ lemur/manage.py | 4 +-- package.json | 8 +++-- setup.py | 28 +++++++++++++-- 9 files changed, 186 insertions(+), 13 deletions(-) create mode 100644 Makefile create mode 100644 docs/requirements.txt create mode 100644 gulp/karma.conf.js diff --git a/.gitignore b/.gitignore index 3235fc47..7505ec58 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ pip-log.txt docs/_build .editorconfig .idea +test.conf +lemur/tests/tmp \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 83f4e22f..51250545 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,27 @@ -language: node_js -node_js: - - '0.8' - - '0.10' +sudo: false +language: python +services: + - postgresql +python: + - "2.7" +cache: + directories: + - node_modules + - .pip_download_cache + - "$HOME/virtualenv/python2.7.9" +env: + global: + - PIP_DOWNLOAD_CACHE=".pip_download_cache" +install: + - time make develop dev-postgres before_script: - - 'npm install -g bower grunt-cli' - - 'bower install' + - psql -c 'create database lemur;' -U postgres +script: + - make lint + - make test-js + - py.test tests + - make test-cli + +notifications: + email: + kglisson@netflix.com \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..a7ffcdcf --- /dev/null +++ b/Makefile @@ -0,0 +1,83 @@ +NPM_ROOT = ./node_modules +STATIC_DIR = src/lemur/static/app + +develop: update-submodules setup-git + @echo "--> Installing dependencies" + npm install + pip install "setuptools>=0.9.8" + # order matters here, base package must install first + pip install -e . + pip install "file://`pwd`#egg=lemur[dev]" + pip install "file://`pwd`#egg=lemur[tests]" + @echo "" + +dev-docs: + pip install -r docs/requirements.txt + +reset-db: + @echo "--> Dropping existing 'lemur' database" + dropdb lemur || true + @echo "--> Creating 'lemur' database" + createdb -E utf-8 lemur + @echo "--> Applying migrations" + lemur db upgrade + +setup-git: + @echo "--> Installing git hooks" + git config branch.autosetuprebase always + cd .git/hooks && ln -sf ../../hooks/* ./ + @echo "" + +clean: + @echo "--> Cleaning static cache" + ${NPM_ROOT}/.bin/gulp clean + @echo "--> Cleaning pyc files" + find . -name "*.pyc" -delete + @echo "" + +test: develop lint test-js test-python test-cli + +testloop: develop + pip install pytest-xdist + py.test tests -f + +test-cli: + @echo "--> Testing CLI" + rm -rf test_cli + mkdir test_cli + cd test_cli && lemur create_config -c ./test.conf > /dev/null + cd test_cli && lemur -c ./test.conf db upgrade > /dev/null + cd test_cli && lemur -c ./test.conf help 2>&1 | grep start > /dev/null + rm -r test_cli + @echo "" + +test-js: + @echo "--> Running JavaScript tests" + npm test + @echo "" + +test-python: + @echo "--> Running Python tests" + py.test lemur/tests || exit 1 + @echo "" + +lint: lint-python lint-js + +lint-python: + @echo "--> Linting Python files" + PYFLAKES_NODOCTEST=1 flake8 lemur tests + @echo "" + +lint-js: + @echo "--> Linting JavaScript files" + npm run lint + @echo "" + +coverage: develop + coverage run --source=lemur -m py.test + coverage html + +publish: + python setup.py sdist bdist_wheel upload + +.PHONY: develop dev-postgres dev-docs setup-git build clean update-submodules test testloop test-cli test-js test-python lint lint-python lint-js coverage publish \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..a77fbe3d --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,5 @@ +Jinja2>=2.3 +Pygments>=1.2 +Sphinx>=1.3 +docutils>=0.7 +markupsafe \ No newline at end of file diff --git a/gulp/build.js b/gulp/build.js index 9326d6be..c6c48a2f 100644 --- a/gulp/build.js +++ b/gulp/build.js @@ -26,6 +26,7 @@ var gulp = require('gulp'), imagemin = require('gulp-imagemin'), minifyHtml = require('gulp-minify-html'), bowerFiles = require('main-bower-files'), + karma = require('karma'), replace = require('gulp-replace-task'); @@ -37,6 +38,15 @@ gulp.task('clean', function (cb) { del(['.tmp', 'lemur/static/dist'], cb); }); +gulp.task('test', function (done) { + new karma.Server({ + configFile: __dirname + '/karma.conf.js', + singleRun: true + }, function() { + done(); + }).start(); +}); + gulp.task('dev:fonts', function () { var fileList = [ 'lemur/static/app/vendor/bower_components/bootstrap/dist/fonts/*', diff --git a/gulp/karma.conf.js b/gulp/karma.conf.js new file mode 100644 index 00000000..48c2f9ec --- /dev/null +++ b/gulp/karma.conf.js @@ -0,0 +1,27 @@ +// Contents of: config/karma.conf.js +module.exports = function (config) { + config.set({ + basePath : '../', + + // Fix for "JASMINE is not supported anymore" warning + frameworks : ["jasmine"], + + files : [ + 'app/lib/angular/angular.js', + 'app/lib/angular/angular-*.js', + 'test/lib/angular/angular-mocks.js', + 'app/js/**/*.js', + 'test/unit/**/*.js' + ], + + autoWatch : true, + + browsers : ['Chrome'], + + junitReporter : { + outputFile : 'test_out/unit.xml', + suite : 'unit' + //... + } + }); +} \ No newline at end of file diff --git a/lemur/manage.py b/lemur/manage.py index 8b255e33..8aa9be60 100755 --- a/lemur/manage.py +++ b/lemur/manage.py @@ -480,8 +480,8 @@ def main(): manager.add_command("show_urls", ShowUrls()) manager.add_command("db", MigrateCommand) manager.add_command("init", InitializeApp()) - manager.add_command('create_user', CreateUser()) - manager.add_command('create_role', CreateRole()) + manager.add_command("create_user", CreateUser()) + manager.add_command("create_role", CreateRole()) manager.add_command("sync", Sync()) manager.run() diff --git a/package.json b/package.json index ee027237..ec523c50 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,8 @@ "main-bower-files": "^1.0.2", "require-dir": "~0.3.0", "streamqueue": "^0.1.1", - "uglify-save-license": "^0.4.1" + "uglify-save-license": "^0.4.1", + "karma": "~0.13.2" }, "engines": { "node": ">=0.10.0" @@ -59,9 +60,12 @@ "scripts": { "postinstall": "bower install --allow-root", "pretest": "npm install && npm run build_static", - "build_static": "gulp dist", + "build_static": "gulp build", "prelint": "npm install", "lint": "jshint app/", "test": "gulp test" + }, + "devDependencies": { + "karma-chrome-launcher": "^0.2.0" } } diff --git a/setup.py b/setup.py index 93803b95..e5468b2f 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ import os.path from distutils import log from distutils.core import Command from setuptools.command.develop import develop +from setuptools.command.install import install from setuptools.command.sdist import sdist from setuptools import setup from subprocess import check_output @@ -56,6 +57,24 @@ docs_require = [ 'sphinxcontrib-httpdomain' ] +dev_requires = [ + 'flake8>=2.0,<2.1', +] + +class SmartInstall(install): + """ + Installs Lemur into the Python environment. + If the package indicator is missing, this will also force a run of + `build_static` which is required for JavaScript assets and other things. + """ + def _needs_static(self): + return not os.path.exists(os.path.join(ROOT, 'lemur-package.json')) + + def run(self): + if self._needs_static(): + self.run_command('build_static') + install.run(self) + class DevelopWithBuildStatic(develop): def install_for_development(self): self.run_command('build_static') @@ -79,7 +98,7 @@ class BuildStatic(Command): log.info("running [npm install --quiet]") check_output(['npm', 'install', '--quiet'], cwd=ROOT) - log.info("running [gulp buld]") + log.info("running [gulp build]") check_output([os.path.join(ROOT, 'node_modules', '.bin', 'gulp'), 'build'], cwd=ROOT) setup( @@ -94,12 +113,15 @@ setup( install_requires=install_requires, extras_require={ 'tests': tests_require, - 'docs': docs_require + 'docs': docs_require, + 'dev': dev_requires, }, cmdclass={ 'build_static': BuildStatic, 'develop': DevelopWithBuildStatic, - 'sdist': SdistWithBuildStatic + 'sdist': SdistWithBuildStatic, + 'install': SmartInstall + }, entry_points={ 'console_scripts': [ From 6a38eb9f321636e8a00a30f3ae0463eb03590c5c Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 08:42:00 -0700 Subject: [PATCH 02/32] Removing JS tests for now --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a7ffcdcf..1521c9ce 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ clean: find . -name "*.pyc" -delete @echo "" -test: develop lint test-js test-python test-cli +test: develop lint test-python testloop: develop pip install pytest-xdist From c6f7ad2d661e421540663f17e7c094db6de2b59b Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 08:49:34 -0700 Subject: [PATCH 03/32] Making sure that bower exists --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 51250545..af2145d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,14 +13,13 @@ env: global: - PIP_DOWNLOAD_CACHE=".pip_download_cache" install: - - time make develop dev-postgres + - make develop dev-postgres before_script: - psql -c 'create database lemur;' -U postgres + - npm install -g bower script: - make lint - - make test-js - py.test tests - - make test-cli notifications: email: From 1bb34fe20bf6ccbf14eb0b670b902479aa642bfa Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 08:55:45 -0700 Subject: [PATCH 04/32] Adding bower to package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 76a57710..eda80473 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,8 @@ "require-dir": "~0.3.0", "streamqueue": "^0.1.1", "uglify-save-license": "^0.4.1", - "karma": "~0.13.2" + "karma": "~0.13.2", + "bower": "~1.4.1" }, "engines": { "node": ">=0.10.0" From 9e16d04fa27911d330fcaa7483abdee4dc61af5b Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 09:00:54 -0700 Subject: [PATCH 05/32] Removing conflicting dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index eda80473..314cfb3d 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "gulp-imagemin": "^0.6.2", "gulp-inject": "~1.0.1", "gulp-jshint": "^1.10.0", - "gulp-karma": "^0.0.4", "gulp-load-plugins": "^0.5.3", "gulp-minify-html": "~0.1.4", "gulp-ng-annotate": "~0.5.2", From 29203baa3d6cf61731b79082238ea335d7944706 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 09:08:01 -0700 Subject: [PATCH 06/32] Fixing where tests are run --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index af2145d5..e893e71b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_script: - npm install -g bower script: - make lint - - py.test tests + - make tests notifications: email: From aeda0886b8ff110858ab2b290e58ef98d1e1f0b6 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 09:17:29 -0700 Subject: [PATCH 07/32] typo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e893e71b..9e79b3ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_script: - npm install -g bower script: - make lint - - make tests + - make test notifications: email: From 309590fb6b2bbf378641278abfebf9a83e051bd9 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 09:50:33 -0700 Subject: [PATCH 08/32] Removing unneeded directory --- Makefile | 2 +- lemur/manage.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1521c9ce..03369342 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ lint: lint-python lint-js lint-python: @echo "--> Linting Python files" - PYFLAKES_NODOCTEST=1 flake8 lemur tests + PYFLAKES_NODOCTEST=1 flake8 lemur @echo "" lint-js: diff --git a/lemur/manage.py b/lemur/manage.py index 8aa9be60..e8a623c4 100755 --- a/lemur/manage.py +++ b/lemur/manage.py @@ -63,6 +63,12 @@ THREADS_PER_PAGE = 8 CORS = False debug = False +# modify this if you are not using a local database +SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur' + +# this is the secret key used by flask session management +SECRET_KEY = '{flask_secret_key}' + # You should consider storing these separately from your config LEMUR_SECRET_TOKEN = '{secret_token}' LEMUR_ENCRYPTION_KEY = '{encryption_key}' @@ -178,7 +184,8 @@ def generate_settings(): """ output = CONFIG_TEMPLATE.format( encryption_key=base64.b64encode(os.urandom(KEY_LENGTH)), - secret_token=base64.b64encode(os.urandom(KEY_LENGTH)) + secret_token=base64.b64encode(os.urandom(KEY_LENGTH)), + flask_secret_key=base64.b64encode(os.urandom(KEY_LENGTH)), ) return output From 0082b163d2288481a5f2abe4ab9111e5448787b7 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 10:03:02 -0700 Subject: [PATCH 09/32] Adding some flake8 configurations --- setup.cfg | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..a1e4f550 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,12 @@ +[pytest] +python_files=test*.py +addopts=--tb=native -p no:doctest +norecursedirs=bin dist docs htmlcov script hooks node_modules .* {args} + +[flake8] +ignore = F999,E501,E128,E124,E402,W503,E731,F841 +max-line-length = 100 +exclude = .tox,.git,*/migrations/*,lemur/static/*,docs/* + +[wheel] +universal = 1 \ No newline at end of file From c75e20a1ea5a638ff9c8d587011df372d48379aa Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 13:06:13 -0700 Subject: [PATCH 10/32] Pleasing the PEP8 gods --- gulp/karma.conf.js | 2 +- gulpfile.js | 2 +- lemur/__init__.py | 2 +- lemur/analyze/service.py | 6 +- lemur/auth/service.py | 5 +- lemur/auth/views.py | 9 +-- lemur/authorities/service.py | 13 ++-- lemur/authorities/views.py | 4 +- lemur/certificates/exceptions.py | 3 +- lemur/certificates/models.py | 8 +-- lemur/certificates/service.py | 21 +++--- lemur/certificates/sync.py | 4 +- lemur/certificates/verify.py | 4 +- lemur/certificates/views.py | 11 ++- lemur/common/health.py | 3 +- lemur/common/managers.py | 3 +- lemur/common/services/aws/ses.py | 5 +- lemur/common/utils.py | 1 - lemur/constants.py | 2 - lemur/database.py | 11 +-- lemur/decorators.py | 5 +- lemur/default.conf.py | 9 +-- lemur/destinations/models.py | 1 + lemur/destinations/service.py | 1 - lemur/destinations/views.py | 5 +- lemur/domains/models.py | 1 - lemur/domains/service.py | 1 - lemur/elbs/models.py | 4 +- lemur/elbs/service.py | 5 +- lemur/elbs/sync.py | 72 ------------------- lemur/extensions.py | 2 - lemur/factory.py | 2 - lemur/listeners/models.py | 1 - lemur/listeners/service.py | 13 ++-- lemur/manage.py | 20 +++--- lemur/models.py | 21 +++--- lemur/notifications.py | 2 +- lemur/plugins/__init__.py | 4 +- lemur/plugins/base/__init__.py | 2 +- lemur/plugins/base/manager.py | 2 +- lemur/plugins/base/v1.py | 1 + lemur/plugins/bases/__init__.py | 6 +- lemur/plugins/bases/destination.py | 2 +- lemur/plugins/bases/issuer.py | 2 +- lemur/plugins/bases/source.py | 2 +- lemur/plugins/lemur_aws/__init__.py | 2 +- lemur/plugins/lemur_aws/elb.py | 4 +- lemur/plugins/lemur_aws/iam.py | 5 +- lemur/plugins/lemur_aws/plugin.py | 10 +-- lemur/plugins/lemur_aws/sts.py | 18 ++--- lemur/plugins/lemur_cloudca/__init__.py | 2 +- lemur/plugins/lemur_cloudca/plugin.py | 20 ++++-- lemur/plugins/lemur_verisign/__init__.py | 2 +- lemur/plugins/lemur_verisign/constants.py | 1 - lemur/plugins/lemur_verisign/plugin.py | 1 - lemur/plugins/views.py | 1 - lemur/roles/models.py | 1 - lemur/roles/service.py | 2 +- .../app/angular/authentication/services.js | 2 +- .../app/angular/authorities/view/view.js | 2 +- .../app/angular/certificates/view/view.js | 2 +- .../destinations/destination/destination.js | 2 +- lemur/static/app/angular/users/user/user.js | 2 +- lemur/tests/__init__.py | 1 + lemur/tests/certs.py | 2 +- lemur/tests/conftest.py | 1 - lemur/tests/test_accounts.py | 8 ++- lemur/tests/test_authorities.py | 5 +- lemur/tests/test_certificates.py | 5 +- lemur/tests/test_crypto.py | 0 lemur/tests/test_csr.py | 38 ---------- lemur/tests/test_domains.py | 6 +- lemur/tests/test_elb.py | 8 +-- lemur/tests/test_iam.py | 8 +-- lemur/tests/test_issuer_manager.py | 4 +- lemur/tests/test_roles.py | 4 +- lemur/users/models.py | 2 - lemur/users/service.py | 2 - 78 files changed, 170 insertions(+), 308 deletions(-) delete mode 100644 lemur/elbs/sync.py delete mode 100644 lemur/tests/test_crypto.py delete mode 100644 lemur/tests/test_csr.py diff --git a/gulp/karma.conf.js b/gulp/karma.conf.js index 48c2f9ec..b9777c7a 100644 --- a/gulp/karma.conf.js +++ b/gulp/karma.conf.js @@ -24,4 +24,4 @@ module.exports = function (config) { //... } }); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index a9da3d3c..1f79f902 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -27,5 +27,5 @@ gulp.task('default', function () { console.log(c.green + '-------------------------------------------' + c.reset); console.log(Object.keys(gulp.tasks).sort().join('\n')); console.log(''); - return; + }); diff --git a/lemur/__init__.py b/lemur/__init__.py index 59d8fff1..85bb846f 100644 --- a/lemur/__init__.py +++ b/lemur/__init__.py @@ -36,6 +36,7 @@ LEMUR_BLUEPRINTS = ( plugins_bp, ) + def create_app(config=None): app = factory.create_app(app_name=__name__, blueprints=LEMUR_BLUEPRINTS, config=config) configure_hook(app) @@ -61,4 +62,3 @@ def configure_hook(app): response = {'message': 'You are not allow to access this resource'} response.status_code = 403 return response - diff --git a/lemur/analyze/service.py b/lemur/analyze/service.py index 7b17d3db..8c384306 100644 --- a/lemur/analyze/service.py +++ b/lemur/analyze/service.py @@ -4,7 +4,7 @@ :license: Apache, see LICENSE for more details. .. moduleauthor:: Kevin Glisson """ -#def analyze(endpoints, truststores): +# def analyze(endpoints, truststores): # results = {"headings": ["Endpoint"], # "results": [], # "time": datetime.now().strftime("#Y%m%d %H:%M:%S")} @@ -37,7 +37,9 @@ # log.debug(e) # if 'hostname' in str(e): # tests.append('pass') -# result['details'].append("{}: This test passed ssl negotiation but failed hostname verification becuase the hostname is not included in the certificate".format(region)) +# result['details'].append( +# "{}: This test passed ssl negotiation but failed hostname verification because \ +# the hostname is not included in the certificate".format(region)) # elif 'certificate verify failed' in str(e): # tests.append('fail') # result['details'].append("{}: This test failed to verify the SSL certificate".format(region)) diff --git a/lemur/auth/service.py b/lemur/auth/service.py index 6386f6d0..807404b9 100644 --- a/lemur/auth/service.py +++ b/lemur/auth/service.py @@ -28,7 +28,7 @@ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers from lemur.users import service as user_service from lemur.auth.permissions import CertificateOwnerNeed, CertificateCreatorNeed, \ - AuthorityCreatorNeed, AuthorityOwnerNeed, ViewRoleCredentialsNeed + AuthorityCreatorNeed, ViewRoleCredentialsNeed def base64url_decode(data): @@ -143,7 +143,6 @@ def fetch_token_header(token): raise jwt.DecodeError('Invalid header padding') - @identity_loaded.connect def on_identity_loaded(sender, identity): """ @@ -187,5 +186,3 @@ class AuthenticatedResource(Resource): def __init__(self): super(AuthenticatedResource, self).__init__() - - diff --git a/lemur/auth/views.py b/lemur/auth/views.py index fd7255ca..796b42d5 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -9,16 +9,15 @@ import jwt import base64 import requests -from flask import g, Blueprint, current_app, abort +from flask import g, Blueprint, current_app from flask.ext.restful import reqparse, Resource, Api from flask.ext.principal import Identity, identity_changed -from lemur.auth.permissions import admin_permission from lemur.users import service as user_service from lemur.roles import service as role_service from lemur.certificates import service as cert_service -from lemur.auth.service import AuthenticatedResource, create_token, fetch_token_header, get_rsa_public_key +from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_key mod = Blueprint('auth', __name__) @@ -222,7 +221,7 @@ class Ping(Resource): profile['email'], profile['email'], True, - profile.get('thumbnailPhotoUrl'), # incase profile isn't google+ enabled + profile.get('thumbnailPhotoUrl'), # Encase profile isn't google+ enabled roles ) @@ -234,5 +233,3 @@ class Ping(Resource): api.add_resource(Login, '/auth/login', endpoint='login') api.add_resource(Ping, '/auth/ping', endpoint='ping') - - diff --git a/lemur/authorities/service.py b/lemur/authorities/service.py index 25c42e8c..9c0abb95 100644 --- a/lemur/authorities/service.py +++ b/lemur/authorities/service.py @@ -19,6 +19,7 @@ import lemur.certificates.service as cert_service from lemur.plugins.base import plugins + def update(authority_id, active=None, roles=None): """ Update a an authority with new values. @@ -30,7 +31,7 @@ def update(authority_id, active=None, roles=None): """ authority = get(authority_id) if roles: - authority = database.update_list(authority, 'roles', Role, roles) + authority = database.update_list(authority, 'roles', Role, roles) if active: authority.active = active @@ -62,9 +63,9 @@ def create(kwargs): for r in issuer_roles: role = role_service.create( r['name'], - password=r['password'], - description="{0} auto generated role".format(kwargs.get('pluginName')), - username=r['username']) + password=r['password'], + description="{0} auto generated role".format(kwargs.get('pluginName')), + username=r['username']) # the user creating the authority should be able to administer it if role.username == 'admin': @@ -132,7 +133,7 @@ def get_authority_role(ca_name): """ if g.current_user.is_admin: authority = get_by_name(ca_name) - #TODO we should pick admin ca roles for admin + # TODO we should pick admin ca roles for admin return authority.roles[0] else: for role in g.current_user.roles: @@ -156,7 +157,7 @@ def render(args): if filt: terms = filt.split(';') - if 'active' in filt: # this is really weird but strcmp seems to not work here?? + if 'active' in filt: # this is really weird but strcmp seems to not work here?? query = query.filter(Authority.active == terms[1]) else: query = database.filter(query, Authority, terms) diff --git a/lemur/authorities/views.py b/lemur/authorities/views.py index cb1797ed..f449a837 100644 --- a/lemur/authorities/views.py +++ b/lemur/authorities/views.py @@ -183,8 +183,8 @@ class AuthoritiesList(AuthenticatedResource): self.reqparse.add_argument('caDescription', type=str, location='json', required=False) self.reqparse.add_argument('ownerEmail', type=str, location='json', required=True) self.reqparse.add_argument('caDN', type=dict, location='json', required=False) - self.reqparse.add_argument('validityStart', type=str, location='json', required=False) # TODO validate - self.reqparse.add_argument('validityEnd', type=str, location='json', required=False) # TODO validate + self.reqparse.add_argument('validityStart', type=str, location='json', required=False) # TODO validate + self.reqparse.add_argument('validityEnd', type=str, location='json', required=False) # TODO validate self.reqparse.add_argument('extensions', type=dict, location='json', required=False) self.reqparse.add_argument('pluginName', type=str, location='json', required=True) self.reqparse.add_argument('caType', type=str, location='json', required=False) diff --git a/lemur/certificates/exceptions.py b/lemur/certificates/exceptions.py index a9ed6e0a..83437704 100644 --- a/lemur/certificates/exceptions.py +++ b/lemur/certificates/exceptions.py @@ -53,6 +53,7 @@ class UnableToCreateCSR(LemurException): def __str__(self): return repr(self.data['message']) + class UnableToCreatePrivateKey(LemurException): def __init__(self): self.code = 500 @@ -63,6 +64,7 @@ class UnableToCreatePrivateKey(LemurException): def __str__(self): return repr(self.data['message']) + class MissingFiles(LemurException): def __init__(self, path): self.code = 500 @@ -84,4 +86,3 @@ class NoPersistanceFound(LemurException): def __str__(self): return repr(self.data['message']) - diff --git a/lemur/certificates/models.py b/lemur/certificates/models.py index 10e0900d..bfe03d74 100644 --- a/lemur/certificates/models.py +++ b/lemur/certificates/models.py @@ -21,7 +21,7 @@ from lemur.database import db from lemur.domains.models import Domain -from lemur.constants import SAN_NAMING_TEMPLATE, DEFAULT_NAMING_TEMPLATE, NONSTANDARD_NAMING_TEMPLATE +from lemur.constants import SAN_NAMING_TEMPLATE, DEFAULT_NAMING_TEMPLATE from lemur.models import certificate_associations, certificate_destination_associations @@ -110,6 +110,7 @@ def cert_is_san(cert): if len(cert_get_domains(cert)) > 1: return True + def cert_is_wildcard(cert): """ Determines if certificate is a wildcard certificate. @@ -197,8 +198,8 @@ class Certificate(db.Model): owner = Column(String(128)) body = Column(Text()) private_key = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY'))) - challenge = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY'))) # TODO deprecate - csr_config = Column(Text()) # TODO deprecate + challenge = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY'))) # TODO deprecate + csr_config = Column(Text()) # TODO deprecate status = Column(String(128)) deleted = Column(Boolean, index=True) name = Column(String(128)) @@ -266,4 +267,3 @@ class Certificate(db.Model): def as_dict(self): return {c.name: getattr(self, c.name) for c in self.__table__.columns} - diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index b89cf159..75159189 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -27,7 +27,6 @@ from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import rsa - def get(cert_id): """ Retrieves certificate by it's ID. @@ -106,7 +105,7 @@ def mint(issuer_options): csr, private_key = create_csr(issuer_options) - issuer_options['challenge'] = create_challenge() + issuer_options['challenge'] = create_challenge() # TODO deprecate issuer_options['creator'] = g.user.email cert_body, cert_chain = issuer.create_certificate(csr, issuer_options) @@ -212,8 +211,8 @@ def render(args): time_range = args.pop('time_range') destination_id = args.pop('destination_id') show = args.pop('show') - owner = args.pop('owner') - creator = args.pop('creator') # TODO we should enabling filtering by owner + # owner = args.pop('owner') + # creator = args.pop('creator') # TODO we should enabling filtering by owner filt = args.pop('filter') @@ -235,7 +234,7 @@ def render(args): if 'destination' in terms: query = query.filter(Certificate.destinations.any(Destination.id == terms[1])) - elif 'active' in filt: # this is really weird but strcmp seems to not work here?? + elif 'active' in filt: # this is really weird but strcmp seems to not work here?? query = query.filter(Certificate.active == terms[1]) else: query = database.filter(query, Certificate, terms) @@ -288,7 +287,7 @@ def create_csr(csr_config): x509.BasicConstraints(ca=False, path_length=None), critical=True, ) - #for k, v in csr_config.get('extensions', {}).items(): + # for k, v in csr_config.get('extensions', {}).items(): # if k == 'subAltNames': # builder = builder.add_extension( # x509.SubjectAlternativeName([x509.DNSName(n) for n in v]), critical=True, @@ -354,14 +353,16 @@ def create_csr(csr_config): return csr, pem + +# TODO deprecate def create_challenge(): """ Create a random and strongish csr challenge. """ - challenge = ''.join(random.choice(string.ascii_uppercase) for x in range(6)) - challenge += ''.join(random.choice("~!@#$%^&*()_+") for x in range(6)) + challenge = ''.join(random.choice(string.ascii_uppercase) for x in range(6)) # noqa + challenge += ''.join(random.choice("~!@#$%^&*()_+") for x in range(6)) # noqa challenge += ''.join(random.choice(string.ascii_lowercase) for x in range(6)) - challenge += ''.join(random.choice(string.digits) for x in range(6)) + challenge += ''.join(random.choice(string.digits) for x in range(6)) # noqa return challenge @@ -405,5 +406,3 @@ def stats(**kwargs): values.append(count) return {'labels': keys, 'values': values} - - diff --git a/lemur/certificates/sync.py b/lemur/certificates/sync.py index a3ec0d2f..b91af6b1 100644 --- a/lemur/certificates/sync.py +++ b/lemur/certificates/sync.py @@ -21,6 +21,7 @@ from lemur.certificates import service as cert_service from lemur.plugins.base import plugins from lemur.plugins.bases.source import SourcePlugin + def sync(): for plugin in plugins: new = 0 @@ -42,5 +43,4 @@ def sync(): # TODO associated cert with source # TODO update cert if found from different source - # TODO dissassociate source if missing - + # TODO disassociate source if missing diff --git a/lemur/certificates/verify.py b/lemur/certificates/verify.py index 4f3b0332..1e0febec 100644 --- a/lemur/certificates/verify.py +++ b/lemur/certificates/verify.py @@ -30,7 +30,7 @@ def ocsp_verify(cert_path, issuer_chain_path): url, err = p1.communicate() p2 = subprocess.Popen(['openssl', 'ocsp', '-issuer', issuer_chain_path, - '-cert', cert_path, "-url", url.strip()], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + '-cert', cert_path, "-url", url.strip()], stdout=subprocess.PIPE, stderr=subprocess.PIPE) message, err = p2.communicate() if 'error' in message or 'Error' in message: @@ -132,4 +132,4 @@ def verify_string(cert_string, issuer_string): def remove_tmp_file(file_path): - os.remove(file_path) \ No newline at end of file + os.remove(file_path) diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index f94011ce..df5f3737 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -51,7 +51,7 @@ def valid_authority(authority_options): """ Defends against invalid authorities - :param authority_name: + :param authority_options: :return: :raise ValueError: """ name = authority_options['name'] @@ -76,7 +76,7 @@ def pem_str(value, name): """ try: x509.load_pem_x509_certificate(str(value), default_backend()) - except Exception as e: + except Exception: raise ValueError("The parameter '{0}' needs to be a valid PEM string".format(name)) return value @@ -91,12 +91,11 @@ def private_key_str(value, name): """ try: serialization.load_pem_private_key(str(value), None, backend=default_backend()) - except Exception as e: + except Exception: raise ValueError("The parameter '{0}' needs to be a valid RSA private key".format(name)) return value - class CertificatesList(AuthenticatedResource): """ Defines the 'certificates' endpoint """ def __init__(self): @@ -274,8 +273,8 @@ class CertificatesList(AuthenticatedResource): self.reqparse.add_argument('destinations', type=list, default=[], location='json') self.reqparse.add_argument('elbs', type=list, location='json') self.reqparse.add_argument('owner', type=str, location='json') - self.reqparse.add_argument('validityStart', type=str, location='json') # parse date - self.reqparse.add_argument('validityEnd', type=str, location='json') # parse date + self.reqparse.add_argument('validityStart', type=str, location='json') # TODO validate + self.reqparse.add_argument('validityEnd', type=str, location='json') # TODO validate self.reqparse.add_argument('authority', type=valid_authority, location='json') self.reqparse.add_argument('description', type=str, location='json') self.reqparse.add_argument('country', type=str, location='json') diff --git a/lemur/common/health.py b/lemur/common/health.py index 11306de2..e5b6d509 100644 --- a/lemur/common/health.py +++ b/lemur/common/health.py @@ -10,6 +10,7 @@ from flask import Blueprint mod = Blueprint('healthCheck', __name__) + @mod.route('/healthcheck') def health(): - return 'ok' \ No newline at end of file + return 'ok' diff --git a/lemur/common/managers.py b/lemur/common/managers.py index 43079f46..4e693677 100644 --- a/lemur/common/managers.py +++ b/lemur/common/managers.py @@ -8,6 +8,7 @@ """ from flask import current_app + # inspired by https://github.com/getsentry/sentry class InstanceManager(object): def __init__(self, class_list=None, instances=True): @@ -61,4 +62,4 @@ class InstanceManager(object): continue self.cache = results - return results \ No newline at end of file + return results diff --git a/lemur/common/services/aws/ses.py b/lemur/common/services/aws/ses.py index 071437ca..8e5aeb4f 100644 --- a/lemur/common/services/aws/ses.py +++ b/lemur/common/services/aws/ses.py @@ -6,8 +6,8 @@ .. moduleauthor:: Kevin Glisson """ -from flask import current_app import boto.ses +from flask import current_app from lemur.templates.config import env @@ -22,8 +22,7 @@ def send(subject, data, email_type, recipients): :param recipients: """ conn = boto.connect_ses() - #jinja template depending on type + # jinja template depending on type template = env.get_template('{}.html'.format(email_type)) body = template.render(**data) conn.send_email(current_app.config.get("LEMUR_EMAIL"), subject, body, recipients, format='html') - diff --git a/lemur/common/utils.py b/lemur/common/utils.py index b0f1ded7..e776e513 100644 --- a/lemur/common/utils.py +++ b/lemur/common/utils.py @@ -12,7 +12,6 @@ from flask import current_app from flask.ext.restful import marshal from flask.ext.restful.reqparse import RequestParser - from flask.ext.sqlalchemy import Pagination diff --git a/lemur/constants.py b/lemur/constants.py index 15d4bdee..3708bbec 100644 --- a/lemur/constants.py +++ b/lemur/constants.py @@ -6,5 +6,3 @@ SAN_NAMING_TEMPLATE = "SAN-{subject}-{issuer}-{not_before}-{not_after}" DEFAULT_NAMING_TEMPLATE = "{subject}-{issuer}-{not_before}-{not_after}" NONSTANDARD_NAMING_TEMPLATE = "{issuer}-{not_before}-{not_after}" - - diff --git a/lemur/database.py b/lemur/database.py index fe591ced..6de3d964 100644 --- a/lemur/database.py +++ b/lemur/database.py @@ -9,13 +9,11 @@ .. moduleauthor:: Kevin Glisson """ -from flask import current_app - from sqlalchemy import exc from sqlalchemy.sql import and_, or_ from lemur.extensions import db -from lemur.exceptions import AttrNotFound, IntegrityError, DuplicateError +from lemur.exceptions import AttrNotFound, DuplicateError def filter_none(kwargs): @@ -126,7 +124,7 @@ def get(model, value, field="id"): query = session_query(model) try: return query.filter(getattr(model, field) == value).one() - except: + except Exception: return @@ -209,7 +207,7 @@ def sort(query, model, field, direction): direction = getattr(field, direction) query = query.order_by(direction()) return query - except AttributeError as e: + except AttributeError: raise AttrNotFound(field) @@ -274,6 +272,3 @@ def sort_and_page(query, model, args): query = sort(query, model, sort_by, sort_dir) return paginate(query, page, count) - - - diff --git a/lemur/decorators.py b/lemur/decorators.py index d1cb695b..bb37dcf4 100644 --- a/lemur/decorators.py +++ b/lemur/decorators.py @@ -9,6 +9,7 @@ from flask import make_response, request, current_app from functools import update_wrapper +# this is only used for dev def crossdomain(origin=None, methods=None, headers=None, max_age=21600, attach_to_all=True, automatic_options=True): @@ -44,12 +45,10 @@ def crossdomain(origin=None, methods=None, headers=None, h['Access-Control-Allow-Origin'] = origin h['Access-Control-Allow-Methods'] = get_methods() h['Access-Control-Max-Age'] = str(max_age) - #if headers is not None: - h['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, Authorization " # headers + h['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, Authorization " h['Access-Control-Allow-Credentials'] = 'true' return resp f.provide_automatic_options = False return update_wrapper(wrapped_function, f) return decorator - diff --git a/lemur/default.conf.py b/lemur/default.conf.py index 1ca0cc72..c5f760fc 100644 --- a/lemur/default.conf.py +++ b/lemur/default.conf.py @@ -7,18 +7,13 @@ ADMINS = frozenset(['']) THREADS_PER_PAGE = 8 -############# -## General ## -############# +# General # These will need to be set to `True` if you are developing locally CORS = False debug = False -############# -## Logging ## -############# +# Logging LOG_LEVEL = "DEBUG" LOG_FILE = "lemur.log" - diff --git a/lemur/destinations/models.py b/lemur/destinations/models.py index 20f910bc..c4cc8a76 100644 --- a/lemur/destinations/models.py +++ b/lemur/destinations/models.py @@ -12,6 +12,7 @@ from lemur.database import db from lemur.plugins.base import plugins + class Destination(db.Model): __tablename__ = 'destinations' id = Column(Integer, primary_key=True) diff --git a/lemur/destinations/service.py b/lemur/destinations/service.py index d43d64d0..e98e4982 100644 --- a/lemur/destinations/service.py +++ b/lemur/destinations/service.py @@ -107,4 +107,3 @@ def render(args): query = database.sort(query, Destination, sort_by, sort_dir) return database.paginate(query, page, count) - diff --git a/lemur/destinations/views.py b/lemur/destinations/views.py index 10c195ca..5d336e4a 100644 --- a/lemur/destinations/views.py +++ b/lemur/destinations/views.py @@ -229,7 +229,6 @@ class Destinations(AuthenticatedResource): return {'result': True} - class CertificateDestinations(AuthenticatedResource): """ Defines the 'certificate/', endpoint='account') -api.add_resource(CertificateDestinations, '/certificates//destinations', endpoint='certificateDestinations') - +api.add_resource(CertificateDestinations, '/certificates//destinations', + endpoint='certificateDestinations') diff --git a/lemur/domains/models.py b/lemur/domains/models.py index 14f52a3d..0bb62f65 100644 --- a/lemur/domains/models.py +++ b/lemur/domains/models.py @@ -24,4 +24,3 @@ class Domain(db.Model): blob = self.as_dict() blob['certificates'] = [x.id for x in self.certificate] return blob - diff --git a/lemur/domains/service.py b/lemur/domains/service.py index f9452bb3..b1e2d559 100644 --- a/lemur/domains/service.py +++ b/lemur/domains/service.py @@ -61,4 +61,3 @@ def render(args): query = database.sort(query, Domain, sort_by, sort_dir) return database.paginate(query, page, count) - diff --git a/lemur/elbs/models.py b/lemur/elbs/models.py index b334df8f..d57a9f1f 100644 --- a/lemur/elbs/models.py +++ b/lemur/elbs/models.py @@ -6,7 +6,7 @@ .. moduleauthor:: Kevin Glisson """ -from sqlalchemy import Column, BigInteger, String, ForeignKey, DateTime, PassiveDefault, func +from sqlalchemy import Column, BigInteger, String, DateTime, PassiveDefault, func from sqlalchemy.orm import relationship from lemur.database import db @@ -16,7 +16,7 @@ from lemur.listeners.models import Listener class ELB(db.Model): __tablename__ = 'elbs' id = Column(BigInteger, primary_key=True) - #account_id = Column(BigInteger, ForeignKey("accounts.id"), index=True) + # account_id = Column(BigInteger, ForeignKey("accounts.id"), index=True) region = Column(String(32)) name = Column(String(128)) vpc_id = Column(String(128)) diff --git a/lemur/elbs/service.py b/lemur/elbs/service.py index 8aa60ccb..d00110bf 100644 --- a/lemur/elbs/service.py +++ b/lemur/elbs/service.py @@ -14,6 +14,7 @@ from lemur import database from lemur.elbs.models import ELB from lemur.listeners.models import Listener + def get_all(account_id, elb_name): """ Retrieves all ELBs in a given account @@ -112,7 +113,7 @@ def stats(**kwargs): if kwargs.get('active') == 'true': query = query.join(ELB.listeners) - query = query.filter(Listener.certificate_id != None) + query = query.filter(Listener.certificate_id != None) # noqa items = query.group_by(attr).all() @@ -121,5 +122,3 @@ def stats(**kwargs): if key: results.append({"key": key, "y": count}) return results - - diff --git a/lemur/elbs/sync.py b/lemur/elbs/sync.py deleted file mode 100644 index f3d90ab0..00000000 --- a/lemur/elbs/sync.py +++ /dev/null @@ -1,72 +0,0 @@ - -""" -.. module: lemur.elbs.sync - :platform: Unix - :synopsis: This module attempts to sync with AWS and ensure that all elbs - currently available in AWS are available in Lemur as well - - :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more - :license: Apache, see LICENSE for more details. -.. moduleauthor:: Kevin Glisson - -""" - -from flask import current_app -#from lemur.accounts import service as account_service -from lemur.elbs import service as elb_service -#from lemur.common.services.aws.elb import get_all_elbs, get_all_regions - - -def create_new(known, aws, account): - new = 0 - for elb in aws: - for n in known: - if elb.name == n.name: - break - else: - new += 1 - current_app.logger.debug("Creating {0}".format(elb.name)) - try: - elb_service.create(account, elb) - except AttributeError as e: - current_app.logger.exception(e) - return new - - -def remove_missing(known, aws): - deleted = 0 - for ke in known: - for elb in aws: - if elb.name == ke.name: - break - else: - deleted += 1 - current_app.logger.debug("Deleting {0}".format(ke.name)) - elb_service.delete(ke.id) - return deleted - - -def sync_all_elbs(): - for account in account_service.get_all(): - regions = get_all_regions() - for region in regions: - current_app.logger.info("Importing ELBs from '{0}/{1}/{2}'... ".format(account.account_number, account.label, region)) - try: - aws_elbs = get_all_elbs(account.account_number, region) - except Exception as e: - current_app.logger.error("Failed to get ELBS from '{0}/{1}/{2}' reason: {3}".format( - account.label, account.account_number, region, e.message) - ) - continue - - known_elbs = elb_service.get_by_region_and_account(region, account.id) - - new_elbs = create_new(known_elbs, aws_elbs, account) - current_app.logger.info( - "Created {0} new ELBs in '{1}/{2}/{3}'...".format( - new_elbs, account.account_number, account.label, region)) - - deleted_elbs = remove_missing(known_elbs, aws_elbs) - current_app.logger.info( - "Deleted {0} missing ELBs from '{1}/{2}/{3}'...".format( - deleted_elbs, account.account_number, account.label, region)) diff --git a/lemur/extensions.py b/lemur/extensions.py index 07101c4d..8c945f80 100644 --- a/lemur/extensions.py +++ b/lemur/extensions.py @@ -3,7 +3,6 @@ :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more :license: Apache, see LICENSE for more details. """ - from flask.ext.sqlalchemy import SQLAlchemy db = SQLAlchemy() @@ -15,4 +14,3 @@ bcrypt = Bcrypt() from flask.ext.principal import Principal principal = Principal() - diff --git a/lemur/factory.py b/lemur/factory.py index a606700a..f895a136 100644 --- a/lemur/factory.py +++ b/lemur/factory.py @@ -19,7 +19,6 @@ from logging.handlers import RotatingFileHandler from flask import Flask from lemur.common.health import mod as health -from lemur.exceptions import NoEncryptionKeyFound from lemur.extensions import db, migrate, principal @@ -161,7 +160,6 @@ def install_plugins(app): try: plugin = ep.load() except Exception: - import sys import traceback app.logger.error("Failed to load plugin %r:\n%s\n" % (ep.name, traceback.format_exc())) else: diff --git a/lemur/listeners/models.py b/lemur/listeners/models.py index 8f83437d..b72c9b48 100644 --- a/lemur/listeners/models.py +++ b/lemur/listeners/models.py @@ -40,4 +40,3 @@ class Listener(db.Model): blob = self.as_dict() del blob['date_created'] return blob - diff --git a/lemur/listeners/service.py b/lemur/listeners/service.py index 25c19d8e..6f2ae596 100644 --- a/lemur/listeners/service.py +++ b/lemur/listeners/service.py @@ -18,7 +18,7 @@ from lemur.listeners.models import Listener from lemur.elbs import service as elb_service from lemur.certificates import service as certificate_service -#from lemur.common.services.aws.elb import update_listeners, create_new_listeners, delete_listeners +# from lemur.common.services.aws.elb import update_listeners, create_new_listeners, delete_listeners def verify_attachment(certificate_id, elb_account_number): @@ -60,7 +60,7 @@ def create(elb_id, instance_protocol, instance_port, load_balancer_port, load_ba cert = verify_attachment(certificate_id, account_number) listener_tuple = (load_balancer_port, instance_port, load_balancer_protocol, cert.get_art(account_number),) - create_new_listeners(account_number, elb.region, elb.name, [listener_tuple]) + # create_new_listeners(account_number, elb.region, elb.name, [listener_tuple]) return {'message': 'Listener has been created'} @@ -98,7 +98,7 @@ def update(listener_id, **kwargs): database.update(listener) listener_tuple = (listener.load_balancer_port, listener.instance_port, listener.load_balancer_protocol, arn,) - update_listeners(account_number, elb.region, elb.name, [listener_tuple], ports) + # update_listeners(account_number, elb.region, elb.name, [listener_tuple], ports) return {'message': 'Listener has been updated'} @@ -106,7 +106,7 @@ def update(listener_id, **kwargs): def delete(listener_id): # first try to delete the listener in aws listener = get(listener_id) - delete_listeners(listener.elb.account.account_number, listener.elb.region, listener.elb.name, [listener.load_balancer_port]) + # delete_listeners(listener.elb.account.account_number, listener.elb.region, listener.elb.name, [listener.load_balancer_port]) # cleanup operation in lemur database.delete(listener) @@ -149,7 +149,7 @@ def stats(**kwargs): query = query.filter(ELB.account_id == kwargs.get('account_id')) if kwargs.get('active') == 'true': - query = query.filter(Listener.certificate_id != None) + query = query.filter(Listener.certificate_id != None) # noqa items = query.group_by(attr).all() results = [] @@ -157,6 +157,3 @@ def stats(**kwargs): if key: results.append({"key": key, "y": count}) return results - - - diff --git a/lemur/manage.py b/lemur/manage.py index e8a623c4..b104f157 100755 --- a/lemur/manage.py +++ b/lemur/manage.py @@ -20,19 +20,18 @@ from lemur.plugins.base import plugins from lemur.certificates.verify import verify_string from lemur.certificates import sync -from lemur.elbs.sync import sync_all_elbs from lemur import create_app # Needed to be imported so that SQLAlchemy create_all can find our models -from lemur.users.models import User -from lemur.roles.models import Role -from lemur.authorities.models import Authority -from lemur.certificates.models import Certificate -from lemur.destinations.models import Destination -from lemur.domains.models import Domain -from lemur.elbs.models import ELB -from lemur.listeners.models import Listener +from lemur.users.models import User # noqa +from lemur.roles.models import Role # noqa +from lemur.authorities.models import Authority # noqa +from lemur.certificates.models import Certificate # noqa +from lemur.destinations.models import Destination # noqa +from lemur.domains.models import Domain # noqa +from lemur.elbs.models import ELB # noqa +from lemur.listeners.models import Listener # noqa manager = Manager(create_app) manager.add_option('-c', '--config', dest='config') @@ -135,6 +134,7 @@ SQLALCHEMY_DATABASE_URI = '' #VERSIGN_EMAIL = '' """ + @MigrateCommand.command def create(): database.db.create_all() @@ -214,7 +214,7 @@ class Sync(Command): sys.stdout.write("[!] Starting to sync with AWS!\n") try: sync.aws() - #sync_all_elbs() + # sync_all_elbs() sys.stdout.write("[+] Finished syncing with AWS!\n") except Exception as e: sys.stdout.write("[-] Syncing with AWS failed!\n") diff --git a/lemur/models.py b/lemur/models.py index 493e1778..f12e49b6 100644 --- a/lemur/models.py +++ b/lemur/models.py @@ -14,17 +14,18 @@ from sqlalchemy import Column, Integer, ForeignKey from lemur.database import db certificate_associations = db.Table('certificate_associations', - Column('domain_id', Integer, ForeignKey('domains.id')), - Column('certificate_id', Integer, ForeignKey('certificates.id')) -) + Column('domain_id', Integer, ForeignKey('domains.id')), + Column('certificate_id', Integer, ForeignKey('certificates.id')) + ) certificate_destination_associations = db.Table('certificate_destination_associations', - Column('destination_id', Integer, ForeignKey('destinations.id', ondelete='cascade')), - Column('certificate_id', Integer, ForeignKey('certificates.id', ondelete='cascade')) -) + Column('destination_id', Integer, + ForeignKey('destinations.id', ondelete='cascade')), + Column('certificate_id', Integer, + ForeignKey('certificates.id', ondelete='cascade')) + ) roles_users = db.Table('roles_users', - Column('user_id', Integer, ForeignKey('users.id')), - Column('role_id', Integer, ForeignKey('roles.id')) -) - + Column('user_id', Integer, ForeignKey('users.id')), + Column('role_id', Integer, ForeignKey('roles.id')) + ) diff --git a/lemur/notifications.py b/lemur/notifications.py index 09bcfec7..055b6b42 100644 --- a/lemur/notifications.py +++ b/lemur/notifications.py @@ -58,7 +58,7 @@ def _find_superseded(domains): current_app.logger.info("Trying to resolve {0}".format(domain.name)) query = query.filter(Certificate.domains.any(Domain.name.in_([x.name for x in domains]))) - query = query.filter(Certificate.active == True) + query = query.filter(Certificate.active == True) # noqa query = query.filter(Certificate.not_after >= arrow.utcnow().format('YYYY-MM-DD')) ss_list.extend(query.all()) diff --git a/lemur/plugins/__init__.py b/lemur/plugins/__init__.py index d2656990..16450064 100644 --- a/lemur/plugins/__init__.py +++ b/lemur/plugins/__init__.py @@ -1,4 +1,4 @@ from __future__ import absolute_import -from lemur.plugins.base import * # NOQA -from lemur.plugins.bases import * # NOQA +from lemur.plugins.base import * # noqa +from lemur.plugins.bases import * # noqa diff --git a/lemur/plugins/base/__init__.py b/lemur/plugins/base/__init__.py index 7091b27b..107cbcf4 100644 --- a/lemur/plugins/base/__init__.py +++ b/lemur/plugins/base/__init__.py @@ -9,7 +9,7 @@ from __future__ import absolute_import, print_function from lemur.plugins.base.manager import PluginManager -from lemur.plugins.base.v1 import * # NOQA +from lemur.plugins.base.v1 import * # noqa plugins = PluginManager() register = plugins.register diff --git a/lemur/plugins/base/manager.py b/lemur/plugins/base/manager.py index 0ec270d0..12556e7d 100644 --- a/lemur/plugins/base/manager.py +++ b/lemur/plugins/base/manager.py @@ -8,6 +8,7 @@ from flask import current_app from lemur.common.managers import InstanceManager + # inspired by https://github.com/getsentry/sentry class PluginManager(InstanceManager): def __iter__(self): @@ -57,4 +58,3 @@ class PluginManager(InstanceManager): def unregister(self, cls): self.remove('%s.%s' % (cls.__module__, cls.__name__)) return cls - diff --git a/lemur/plugins/base/v1.py b/lemur/plugins/base/v1.py index 2055577b..ce378b98 100644 --- a/lemur/plugins/base/v1.py +++ b/lemur/plugins/base/v1.py @@ -8,6 +8,7 @@ """ from threading import local + # stolen from https://github.com/getsentry/sentry/ class PluginMount(type): def __new__(cls, name, bases, attrs): diff --git a/lemur/plugins/bases/__init__.py b/lemur/plugins/bases/__init__.py index 2e501d35..044bb213 100644 --- a/lemur/plugins/bases/__init__.py +++ b/lemur/plugins/bases/__init__.py @@ -1,3 +1,3 @@ -from .destination import DestinationPlugin # NOQA -from .issuer import IssuerPlugin # NOQA -from .source import SourcePlugin \ No newline at end of file +from .destination import DestinationPlugin # noqa +from .issuer import IssuerPlugin # noqa +from .source import SourcePlugin # noqa diff --git a/lemur/plugins/bases/destination.py b/lemur/plugins/bases/destination.py index b3dcef5f..61c908eb 100644 --- a/lemur/plugins/bases/destination.py +++ b/lemur/plugins/bases/destination.py @@ -8,9 +8,9 @@ """ from lemur.plugins.base import Plugin + class DestinationPlugin(Plugin): type = 'destination' def upload(self): raise NotImplemented - diff --git a/lemur/plugins/bases/issuer.py b/lemur/plugins/bases/issuer.py index bfa7dbd6..29f44a97 100644 --- a/lemur/plugins/bases/issuer.py +++ b/lemur/plugins/bases/issuer.py @@ -8,6 +8,7 @@ """ from lemur.plugins.base import Plugin + class IssuerPlugin(Plugin): """ This is the base class from which all of the supported @@ -20,4 +21,3 @@ class IssuerPlugin(Plugin): def create_authority(self): raise NotImplemented - diff --git a/lemur/plugins/bases/source.py b/lemur/plugins/bases/source.py index a706acf2..9ddae1a0 100644 --- a/lemur/plugins/bases/source.py +++ b/lemur/plugins/bases/source.py @@ -8,6 +8,7 @@ """ from lemur.plugins.base import Plugin + class SourcePlugin(Plugin): type = 'source' @@ -16,4 +17,3 @@ class SourcePlugin(Plugin): def get_options(self): return {} - diff --git a/lemur/plugins/lemur_aws/__init__.py b/lemur/plugins/lemur_aws/__init__.py index d29488d2..e572596e 100644 --- a/lemur/plugins/lemur_aws/__init__.py +++ b/lemur/plugins/lemur_aws/__init__.py @@ -2,4 +2,4 @@ try: VERSION = __import__('pkg_resources') \ .get_distribution(__name__).version except Exception, e: - VERSION = 'unknown' \ No newline at end of file + VERSION = 'unknown' diff --git a/lemur/plugins/lemur_aws/elb.py b/lemur/plugins/lemur_aws/elb.py index 1edfd5b4..d71b5013 100644 --- a/lemur/plugins/lemur_aws/elb.py +++ b/lemur/plugins/lemur_aws/elb.py @@ -38,6 +38,7 @@ def is_valid(listener_tuple): return listener_tuple + def get_all_regions(): """ Retrieves all current EC2 regions. @@ -49,6 +50,7 @@ def get_all_regions(): regions.append(r.name) return regions + def get_all_elbs(account_number, region): """ Fetches all elb objects for a given account and region. @@ -74,7 +76,6 @@ def get_all_elbs(account_number, region): # return elbs - def attach_certificate(account_number, region, name, port, certificate_id): """ Attaches a certificate to a listener, throws exception @@ -137,4 +138,3 @@ def delete_listeners(account_number, region, name, ports): :return: """ return assume_service(account_number, 'elb', region).delete_load_balancer_listeners(name, ports) - diff --git a/lemur/plugins/lemur_aws/iam.py b/lemur/plugins/lemur_aws/iam.py index fa8e50e0..63971958 100644 --- a/lemur/plugins/lemur_aws/iam.py +++ b/lemur/plugins/lemur_aws/iam.py @@ -44,7 +44,8 @@ def upload_cert(account_number, cert, private_key, cert_chain=None): :param cert_chain: :return: """ - return assume_service(account_number, 'iam').upload_server_cert(cert.name, str(cert.body), str(private_key), cert_chain=str(cert_chain)) + return assume_service(account_number, 'iam').upload_server_cert(cert.name, str(cert.body), str(private_key), + cert_chain=str(cert_chain)) def delete_cert(account_number, cert): @@ -109,5 +110,3 @@ def digest_aws_cert_response(response): chain = cert['certificate_chain'] return str(body), str(chain), - - diff --git a/lemur/plugins/lemur_aws/plugin.py b/lemur/plugins/lemur_aws/plugin.py index 35800f51..7eec91c9 100644 --- a/lemur/plugins/lemur_aws/plugin.py +++ b/lemur/plugins/lemur_aws/plugin.py @@ -35,11 +35,11 @@ class AWSDestinationPlugin(DestinationPlugin): 'helpMessage': 'Must be a valid AWS account number!', } ] - #'elb': { - # 'name': {'type': 'name'}, - # 'region': {'type': 'str'}, - # 'port': {'type': 'int'} - #} + # 'elb': { + # 'name': {'type': 'name'}, + # 'region': {'type': 'str'}, + # 'port': {'type': 'int'} + # } def upload(self, cert, private_key, cert_chain, options, **kwargs): iam.upload_cert(find_value('accountNumber', options), cert, private_key, cert_chain=cert_chain) diff --git a/lemur/plugins/lemur_aws/sts.py b/lemur/plugins/lemur_aws/sts.py index f53a545b..843cf0f8 100644 --- a/lemur/plugins/lemur_aws/sts.py +++ b/lemur/plugins/lemur_aws/sts.py @@ -25,17 +25,13 @@ def assume_service(account_number, service, region=None): elif service in 'elb': return boto.ec2.elb.connect_to_region( - region, - aws_access_key_id=role.credentials.access_key, - aws_secret_access_key=role.credentials.secret_key, - security_token=role.credentials.session_token) + region, + aws_access_key_id=role.credentials.access_key, + aws_secret_access_key=role.credentials.secret_key, + security_token=role.credentials.session_token) elif service in 'vpc': return boto.connect_vpc( - aws_access_key_id=role.credentials.access_key, - aws_secret_access_key=role.credentials.secret_key, - security_token=role.credentials.session_token) - - - - + aws_access_key_id=role.credentials.access_key, + aws_secret_access_key=role.credentials.secret_key, + security_token=role.credentials.session_token) diff --git a/lemur/plugins/lemur_cloudca/__init__.py b/lemur/plugins/lemur_cloudca/__init__.py index d29488d2..e572596e 100644 --- a/lemur/plugins/lemur_cloudca/__init__.py +++ b/lemur/plugins/lemur_cloudca/__init__.py @@ -2,4 +2,4 @@ try: VERSION = __import__('pkg_resources') \ .get_distribution(__name__).version except Exception, e: - VERSION = 'unknown' \ No newline at end of file + VERSION = 'unknown' diff --git a/lemur/plugins/lemur_cloudca/plugin.py b/lemur/plugins/lemur_cloudca/plugin.py index 68de48d3..229e58a7 100644 --- a/lemur/plugins/lemur_cloudca/plugin.py +++ b/lemur/plugins/lemur_cloudca/plugin.py @@ -23,7 +23,7 @@ from lemur.plugins import lemur_cloudca as cloudca from lemur.authorities import service as authority_service -API_ENDPOINT = '/v1/ca/netflix' # TODO this should be configurable +API_ENDPOINT = '/v1/ca/netflix' # TODO this should be configurable class CloudCAException(LemurException): @@ -72,7 +72,8 @@ def get_default_issuance(options): if not options.get('validityStart') and not options.get('validityEnd'): start = arrow.utcnow() options['validityStart'] = start.floor('second').isoformat() - options['validityEnd'] = start.replace(years=current_app.config.get('CLOUDCA_DEFAULT_VALIDITY')).ceil('second').isoformat() + options['validityEnd'] = start.replace(years=current_app.config.get('CLOUDCA_DEFAULT_VALIDITY'))\ + .ceil('second').isoformat() return options @@ -95,7 +96,8 @@ def convert_date_to_utc_time(date): :return: """ d = arrow.get(date) - return arrow.utcnow().replace(day=d.naive.day).replace(month=d.naive.month).replace(year=d.naive.year).replace(microsecond=0) + return arrow.utcnow().replace(day=d.naive.day).replace(month=d.naive.month).replace(year=d.naive.year)\ + .replace(microsecond=0) def process_response(response): @@ -152,7 +154,9 @@ class CloudCA(object): self.session.cert = current_app.config.get('CLOUDCA_PEM_PATH') self.ca_bundle = current_app.config.get('CLOUDCA_BUNDLE') else: - current_app.logger.warning("No CLOUDCA credentials found, lemur will be unable to request certificates from CLOUDCA") + current_app.logger.warning( + "No CLOUDCA credentials found, lemur will be unable to request certificates from CLOUDCA" + ) super(CloudCA, self).__init__(*args, **kwargs) @@ -203,7 +207,7 @@ class CloudCA(object): for ca in self.get(endpoint)['data']['caList']: try: authorities.append(ca['caName']) - except AttributeError as e: + except AttributeError: current_app.logger.error("No authority has been defined for {}".format(ca['caName'])) return authorities @@ -235,7 +239,8 @@ class CloudCAIssuerPlugin(IssuerPlugin, CloudCA): options['validityStart'] = convert_date_to_utc_time(options['validityStart']).isoformat() options['validityEnd'] = convert_date_to_utc_time(options['validityEnd']).isoformat() - response = self.session.post(self.url + endpoint, data=dumps(remove_none(options)), timeout=10, verify=self.ca_bundle) + response = self.session.post(self.url + endpoint, data=dumps(remove_none(options)), timeout=10, + verify=self.ca_bundle) json = process_response(response) roles = [] @@ -326,7 +331,8 @@ class CloudCASourcePlugin(SourcePlugin, CloudCA): :return: """ endpoint = '{0}/getCert'.format(API_ENDPOINT) - response = self.session.post(self.url + endpoint, data=dumps({'caName': ca_name}), timeout=10, verify=self.ca_bundle) + response = self.session.post(self.url + endpoint, data=dumps({'caName': ca_name}), timeout=10, + verify=self.ca_bundle) raw = process_response(response) certs = [] diff --git a/lemur/plugins/lemur_verisign/__init__.py b/lemur/plugins/lemur_verisign/__init__.py index d29488d2..e572596e 100644 --- a/lemur/plugins/lemur_verisign/__init__.py +++ b/lemur/plugins/lemur_verisign/__init__.py @@ -2,4 +2,4 @@ try: VERSION = __import__('pkg_resources') \ .get_distribution(__name__).version except Exception, e: - VERSION = 'unknown' \ No newline at end of file + VERSION = 'unknown' diff --git a/lemur/plugins/lemur_verisign/constants.py b/lemur/plugins/lemur_verisign/constants.py index 0f90ed98..b7ea6a53 100644 --- a/lemur/plugins/lemur_verisign/constants.py +++ b/lemur/plugins/lemur_verisign/constants.py @@ -55,4 +55,3 @@ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- """ - diff --git a/lemur/plugins/lemur_verisign/plugin.py b/lemur/plugins/lemur_verisign/plugin.py index eb00907d..ef080e83 100644 --- a/lemur/plugins/lemur_verisign/plugin.py +++ b/lemur/plugins/lemur_verisign/plugin.py @@ -151,4 +151,3 @@ class VerisignIssuerPlugin(IssuerPlugin): url = current_app.config.get("VERISIGN_URL") + '/getTokens' response = self.session.post(url, headers={'content-type': 'application/x-www-form-urlencoded'}) return handle_response(response.content)['Response']['Order'] - diff --git a/lemur/plugins/views.py b/lemur/plugins/views.py index a1b7a000..eb774415 100644 --- a/lemur/plugins/views.py +++ b/lemur/plugins/views.py @@ -137,4 +137,3 @@ class PluginsTypeList(AuthenticatedResource): api.add_resource(PluginsList, '/plugins', endpoint='plugins') api.add_resource(PluginsTypeList, '/plugins/', endpoint='pluginType') - diff --git a/lemur/roles/models.py b/lemur/roles/models.py index 9df2a4fb..08781c6c 100644 --- a/lemur/roles/models.py +++ b/lemur/roles/models.py @@ -36,4 +36,3 @@ class Role(db.Model): def serialize(self): blob = self.as_dict() return blob - diff --git a/lemur/roles/service.py b/lemur/roles/service.py index 92c1011d..4e879143 100644 --- a/lemur/roles/service.py +++ b/lemur/roles/service.py @@ -15,6 +15,7 @@ from lemur import database from lemur.roles.models import Role from lemur.users.models import User + def update(role_id, name, description, users): """ Update a role @@ -122,4 +123,3 @@ def render(args): query = database.sort(query, Role, sort_by, sort_dir) return database.paginate(query, page, count) - diff --git a/lemur/static/app/angular/authentication/services.js b/lemur/static/app/angular/authentication/services.js index 7230a41d..193989e0 100644 --- a/lemur/static/app/angular/authentication/services.js +++ b/lemur/static/app/angular/authentication/services.js @@ -41,7 +41,7 @@ angular.module('lemur') }); } ); - } + }; AuthenticationService.logout = function () { if (!$auth.isAuthenticated()) { diff --git a/lemur/static/app/angular/authorities/view/view.js b/lemur/static/app/angular/authorities/view/view.js index 0208307f..0ee16082 100644 --- a/lemur/static/app/angular/authorities/view/view.js +++ b/lemur/static/app/angular/authorities/view/view.js @@ -35,7 +35,7 @@ angular.module('lemur') $scope.getAuthorityStatus = function () { var def = $q.defer(); - def.resolve([{'title': 'Active', 'id': true}, {'title': 'Inactive', 'id': false}]) + def.resolve([{'title': 'Active', 'id': true}, {'title': 'Inactive', 'id': false}]); return def; }; diff --git a/lemur/static/app/angular/certificates/view/view.js b/lemur/static/app/angular/certificates/view/view.js index 230f9181..3c295f84 100644 --- a/lemur/static/app/angular/certificates/view/view.js +++ b/lemur/static/app/angular/certificates/view/view.js @@ -48,7 +48,7 @@ angular.module('lemur') $scope.getCertificateStatus = function () { var def = $q.defer(); - def.resolve([{'title': 'Active', 'id': true}, {'title': 'Inactive', 'id': false}]) + def.resolve([{'title': 'Active', 'id': true}, {'title': 'Inactive', 'id': false}]); return def; }; diff --git a/lemur/static/app/angular/destinations/destination/destination.js b/lemur/static/app/angular/destinations/destination/destination.js index 15fb2b42..7ef85dd1 100644 --- a/lemur/static/app/angular/destinations/destination/destination.js +++ b/lemur/static/app/angular/destinations/destination/destination.js @@ -32,7 +32,7 @@ angular.module('lemur') DestinationService.update(destination).then(function () { $modalInstance.close(); }); - } + }; $scope.cancel = function () { $modalInstance.dismiss('cancel'); diff --git a/lemur/static/app/angular/users/user/user.js b/lemur/static/app/angular/users/user/user.js index 7a3524f2..99de4d0e 100644 --- a/lemur/static/app/angular/users/user/user.js +++ b/lemur/static/app/angular/users/user/user.js @@ -18,7 +18,7 @@ angular.module('lemur') UserService.update(user).then(function () { $modalInstance.close(); }); - } + }; $scope.cancel = function () { $modalInstance.dismiss('cancel'); diff --git a/lemur/tests/__init__.py b/lemur/tests/__init__.py index c293a1cc..27dc8f42 100644 --- a/lemur/tests/__init__.py +++ b/lemur/tests/__init__.py @@ -1,4 +1,5 @@ import unittest + class LemurTestCase(unittest.TestCase): pass diff --git a/lemur/tests/certs.py b/lemur/tests/certs.py index ce2f123b..d71d2064 100644 --- a/lemur/tests/certs.py +++ b/lemur/tests/certs.py @@ -218,4 +218,4 @@ CSR_CONFIG = """ [alt_names] # Put your SANs here -""" \ No newline at end of file +""" diff --git a/lemur/tests/conftest.py b/lemur/tests/conftest.py index 849a3a7d..de9b3f44 100644 --- a/lemur/tests/conftest.py +++ b/lemur/tests/conftest.py @@ -73,4 +73,3 @@ def session(db, request): @pytest.yield_fixture(scope="function") def client(app, session, client): yield client - diff --git a/lemur/tests/test_accounts.py b/lemur/tests/test_accounts.py index c5dec77e..f91c6525 100644 --- a/lemur/tests/test_accounts.py +++ b/lemur/tests/test_accounts.py @@ -1,5 +1,5 @@ -from lemur.destinations.service import * -from lemur.destinations.views import * +from lemur.destinations.service import * # noqa +from lemur.destinations.views import * # noqa from json import dumps @@ -40,6 +40,7 @@ def test_destination_patch(client): VALID_USER_HEADER_TOKEN = { 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'} + def test_auth_destination_get(client): assert client.get(api.url_for(Destinations, destination_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200 @@ -63,6 +64,7 @@ def test_auth_destination_patch(client): VALID_ADMIN_HEADER_TOKEN = { 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'} + def test_admin_destination_get(client): assert client.get(api.url_for(Destinations, destination_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 @@ -120,7 +122,7 @@ def test_admin_destinations_get(client): def test_admin_destinations_crud(client): assert client.post(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400 data = {'destinationNumber': 111, 'label': 'test', 'comments': 'test'} - resp = client.post(api.url_for(DestinationsList), data=dumps(data), content_type='application/json', headers=VALID_ADMIN_HEADER_TOKEN) + resp = client.post(api.url_for(DestinationsList), data=dumps(data), content_type='application/json', headers=VALID_ADMIN_HEADER_TOKEN) assert resp.status_code == 200 assert client.get(api.url_for(Destinations, destination_id=resp.json['id']), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 resp = client.get(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN) diff --git a/lemur/tests/test_authorities.py b/lemur/tests/test_authorities.py index e66147e5..3d9becbd 100644 --- a/lemur/tests/test_authorities.py +++ b/lemur/tests/test_authorities.py @@ -1,7 +1,6 @@ -import pytest -from lemur.authorities.views import * +from lemur.authorities.views import * # noqa -#def test_crud(session): +# def test_crud(session): # role = create('role1') # assert role.id > 0 # diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index 5990c09c..3d2757a4 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -1,5 +1,6 @@ import pytest -from lemur.certificates.views import * +from lemur.certificates.views import * # noqa + def test_valid_authority(session): assert 1 == 2 @@ -87,6 +88,7 @@ def test_cert_get_bitstrength(): from lemur.certificates.models import cert_get_bitstrength assert cert_get_bitstrength(INTERNAL_VALID_LONG_CERT) == 2048 + def test_cert_get_issuer(): from lemur.tests.certs import INTERNAL_VALID_LONG_CERT from lemur.certificates.models import cert_get_issuer @@ -324,4 +326,3 @@ def test_admin_certificate_credentials_delete(client): def test_admin_certificate_credentials_patch(client): assert client.patch(api.url_for(CertificatePrivateKey, certificate_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405 - diff --git a/lemur/tests/test_crypto.py b/lemur/tests/test_crypto.py deleted file mode 100644 index e69de29b..00000000 diff --git a/lemur/tests/test_csr.py b/lemur/tests/test_csr.py deleted file mode 100644 index 25633a4a..00000000 --- a/lemur/tests/test_csr.py +++ /dev/null @@ -1,38 +0,0 @@ -TEST_CSR = """ - # Configuration for standard CSR generation for Netflix - # Used for procuring VeriSign certificates - # Author: jachan - # Contact: cloudsecurity@netflix.com - - [ req ] - # Use a 2048 bit private key - default_bits = 2048 - default_keyfile = key.pem - prompt = no - encrypt_key = no - - # base request - distinguished_name = req_distinguished_name - - # extensions - # Uncomment the following line if you are requesting a SAN cert - {is_san_comment}req_extensions = req_ext - - # distinguished_name - [ req_distinguished_name ] - countryName = "US" # C= - stateOrProvinceName = "CALIFORNIA" # ST= - localityName = "Los Gatos" # L= - organizationName = "Netflix, Inc." # O= - organizationalUnitName = "Operations" # OU= - # This is the hostname/subject name on the certificate - commonName = "{DNS[0]}" # CN= - - [ req_ext ] - # Uncomment the following line if you are requesting a SAN cert - {is_san_comment}subjectAltName = @alt_names - - [alt_names] - # Put your SANs here - {DNS_LINES} - """ diff --git a/lemur/tests/test_domains.py b/lemur/tests/test_domains.py index e8f94728..85909f72 100644 --- a/lemur/tests/test_domains.py +++ b/lemur/tests/test_domains.py @@ -1,4 +1,5 @@ -from lemur.domains.views import * +from lemur.domains.views import * # noqa + def test_domain_get(client): assert client.get(api.url_for(Domains, domain_id=1)).status_code == 401 @@ -23,6 +24,7 @@ def test_domain_patch(client): VALID_USER_HEADER_TOKEN = { 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'} + def test_auth_domain_get(client): assert client.get(api.url_for(Domains, domain_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200 @@ -46,6 +48,7 @@ def test_auth_domain_patch(client): VALID_ADMIN_HEADER_TOKEN = { 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'} + def test_admin_domain_get(client): assert client.get(api.url_for(Domains, domain_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 @@ -119,5 +122,6 @@ def test_certificate_domains_patch(client): def test_auth_certificate_domains_get(client): assert client.get(api.url_for(CertificateDomains, certificate_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200 + def test_admin_certificate_domains_get(client): assert client.get(api.url_for(CertificateDomains, certificate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 diff --git a/lemur/tests/test_elb.py b/lemur/tests/test_elb.py index bc4a10c7..e336aaf2 100644 --- a/lemur/tests/test_elb.py +++ b/lemur/tests/test_elb.py @@ -1,10 +1,10 @@ -import boto -from lemur.tests import LemurTestCase +# import boto +# from lemur.tests import LemurTestCase -from moto import mock_elb, mock_sts +# from moto import mock_elb, mock_sts -#class ELBTestCase(LemurTestCase): +# class ELBTestCase(LemurTestCase): # @mock_sts # @mock_elb # def test_add_listener(self): diff --git a/lemur/tests/test_iam.py b/lemur/tests/test_iam.py index 2405f9b5..89e1a6fc 100644 --- a/lemur/tests/test_iam.py +++ b/lemur/tests/test_iam.py @@ -1,11 +1,11 @@ -from lemur.tests import LemurTestCase +# from lemur.tests import LemurTestCase -from lemur.certificates.models import Certificate +# from lemur.certificates.models import Certificate -from moto import mock_iam, mock_sts +# from moto import mock_iam, mock_sts -#class IAMTestCase(LemurTestCase): +# class IAMTestCase(LemurTestCase): # @mock_sts # @mock_iam # def test_get_all_server_certs(self): diff --git a/lemur/tests/test_issuer_manager.py b/lemur/tests/test_issuer_manager.py index 5eaec09b..e3472400 100644 --- a/lemur/tests/test_issuer_manager.py +++ b/lemur/tests/test_issuer_manager.py @@ -1,6 +1,6 @@ -from lemur.tests import LemurTestCase +# from lemur.tests import LemurTestCase -#class ManagerTestCase(LemurTestCase): +# class ManagerTestCase(LemurTestCase): # def test_validate_authority(self): # pass # diff --git a/lemur/tests/test_roles.py b/lemur/tests/test_roles.py index 7339aeb4..e14b6c61 100644 --- a/lemur/tests/test_roles.py +++ b/lemur/tests/test_roles.py @@ -1,6 +1,6 @@ from json import dumps -from lemur.roles.service import * -from lemur.roles.views import * +from lemur.roles.service import * # noqa +from lemur.roles.views import * # noqa def test_crud(session): diff --git a/lemur/users/models.py b/lemur/users/models.py index 08b341e7..a3a13b1e 100644 --- a/lemur/users/models.py +++ b/lemur/users/models.py @@ -84,5 +84,3 @@ class User(db.Model): listen(User, 'before_insert', hash_password) - - diff --git a/lemur/users/service.py b/lemur/users/service.py index c4eebcee..79b77a14 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -145,5 +145,3 @@ def render(args): query = database.sort(query, User, sort_by, sort_dir) return database.paginate(query, page, count) - - From a826bd16f795d3c373995b8c62266df04079b33a Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 13:36:03 -0700 Subject: [PATCH 11/32] Pleasing the JSHint gods --- .jshintignore | 6 ++---- lemur/static/app/angular/app.js | 8 ++++---- lemur/static/app/angular/authentication/services.js | 4 ++-- .../app/angular/authorities/authority/authority.js | 4 ++-- .../angular/certificates/certificate/certificate.js | 2 +- lemur/static/app/angular/certificates/services.js | 13 ++++++------- lemur/static/app/angular/components/filters.js | 2 ++ lemur/static/app/angular/dashboard/dashboard.js | 9 ++++----- lemur/static/app/angular/domains/services.js | 2 ++ lemur/static/app/angular/elbs/services.js | 4 +++- lemur/static/app/angular/listeners/services.js | 2 ++ lemur/static/app/angular/plugins/services.js | 2 ++ lemur/static/app/angular/roles/services.js | 4 +++- package.json | 3 ++- 14 files changed, 37 insertions(+), 28 deletions(-) diff --git a/.jshintignore b/.jshintignore index 82755159..55644736 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,4 +1,2 @@ -tests/ -lemur/static/lemur/scripts/lib/ -lemur/static/lemur/dist/ -lemur/static/lemur/vendor/ \ No newline at end of file +lemur/static//dist/ +lemur/static/app/vendor/ \ No newline at end of file diff --git a/lemur/static/app/angular/app.js b/lemur/static/app/angular/app.js index 3ed03188..2f0cc90a 100644 --- a/lemur/static/app/angular/app.js +++ b/lemur/static/app/angular/app.js @@ -65,11 +65,11 @@ lemur.factory('LemurRestangular', function (Restangular, $location, $auth) { RestangularConfigurer.setBaseUrl('http://localhost:5000/api/1'); RestangularConfigurer.setDefaultHttpFields({withCredentials: true}); - RestangularConfigurer.addResponseInterceptor(function (data, operation, what, url, response, deferred) { + RestangularConfigurer.addResponseInterceptor(function (data, operation) { var extractedData; // .. to look for getList operations - if (operation === "getList") { + if (operation === 'getList') { // .. and handle the data and meta data extractedData = data.items; extractedData.total = data.total; @@ -79,7 +79,7 @@ lemur.factory('LemurRestangular', function (Restangular, $location, $auth) { return extractedData; }); - RestangularConfigurer.addFullRequestInterceptor(function (element, operation, route, url, headers, params, httpConfig) { + RestangularConfigurer.addFullRequestInterceptor(function (element, operation, route, url, headers, params) { // We want to make sure the user is auth'd before any requests if (!$auth.isAuthenticated()) { $location.path('/login'); @@ -97,7 +97,7 @@ lemur.factory('LemurRestangular', function (Restangular, $location, $auth) { newParams.sortDir = params[item]; } else if (item.indexOf(f) > -1) { var key = regExp.exec(item)[1]; - newParams['filter'] = key + ";" + params[item]; + newParams.filter = key + ';' + params[item]; } else { newParams[item] = params[item]; } diff --git a/lemur/static/app/angular/authentication/services.js b/lemur/static/app/angular/authentication/services.js index 193989e0..dddffeb4 100644 --- a/lemur/static/app/angular/authentication/services.js +++ b/lemur/static/app/angular/authentication/services.js @@ -28,7 +28,7 @@ angular.module('lemur') AuthenticationService.authenticate = function (provider) { $auth.authenticate(provider) .then( - function (user) { + function () { UserService.getCurrentUser(); $rootScope.$emit('user:login'); $location.url('/certificates'); @@ -56,7 +56,7 @@ angular.module('lemur') body: 'You have been successfully logged out.' }); $location.path('/'); - }) + }); }; }); diff --git a/lemur/static/app/angular/authorities/authority/authority.js b/lemur/static/app/angular/authorities/authority/authority.js index e5f4ffc2..419e49fd 100644 --- a/lemur/static/app/angular/authorities/authority/authority.js +++ b/lemur/static/app/angular/authorities/authority/authority.js @@ -19,10 +19,10 @@ angular.module('lemur') $scope.loading = false; $scope.create = function (authority) { WizardHandler.wizard().context.loading = true; - AuthorityService.create(authority).then(function (resposne) { + AuthorityService.create(authority).then(function () { WizardHandler.wizard().context.loading = false; $modalInstance.close(); - }) + }); }; PluginService.get('issuer').then(function (plugins) { diff --git a/lemur/static/app/angular/certificates/certificate/certificate.js b/lemur/static/app/angular/certificates/certificate/certificate.js index c2c47f0f..9a166050 100644 --- a/lemur/static/app/angular/certificates/certificate/certificate.js +++ b/lemur/static/app/angular/certificates/certificate/certificate.js @@ -16,7 +16,7 @@ angular.module('lemur') $scope.create = function (certificate) { WizardHandler.wizard().context.loading = true; - CertificateService.create(certificate).then(function (response) { + CertificateService.create(certificate).then(function () { WizardHandler.wizard().context.loading = false; $modalInstance.close(); }); diff --git a/lemur/static/app/angular/certificates/services.js b/lemur/static/app/angular/certificates/services.js index bb7eba53..504c2bcd 100644 --- a/lemur/static/app/angular/certificates/services.js +++ b/lemur/static/app/angular/certificates/services.js @@ -1,6 +1,5 @@ -/** - * Created by kglisson on 1/19/15. - */ +'use strict'; + angular.module('lemur') .service('CertificateApi', function (LemurRestangular, DomainService) { LemurRestangular.extendModel('certificates', function (obj) { @@ -102,7 +101,7 @@ angular.module('lemur') CertificateService.create = function (certificate) { certificate.attachSubAltName(); return CertificateApi.post(certificate).then( - function (response) { + function () { toaster.pop({ type: 'success', title: certificate.name, @@ -132,8 +131,8 @@ angular.module('lemur') }; CertificateService.upload = function (certificate) { - CertificateApi.customPOST(certificate, "upload").then( - function (response) { + CertificateApi.customPOST(certificate, 'upload').then( + function () { toaster.pop({ type: 'success', title: certificate.name, @@ -163,7 +162,7 @@ angular.module('lemur') certificate.privateKey = response.key; } }, - function (response) { + function () { toaster.pop({ type: 'error', title: certificate.name, diff --git a/lemur/static/app/angular/components/filters.js b/lemur/static/app/angular/components/filters.js index 6229e25d..4e316fe7 100644 --- a/lemur/static/app/angular/components/filters.js +++ b/lemur/static/app/angular/components/filters.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('lemur'). filter('titleCase', function () { return function (str) { diff --git a/lemur/static/app/angular/dashboard/dashboard.js b/lemur/static/app/angular/dashboard/dashboard.js index 8e88d66b..f0d94eab 100644 --- a/lemur/static/app/angular/dashboard/dashboard.js +++ b/lemur/static/app/angular/dashboard/dashboard.js @@ -7,9 +7,8 @@ angular.module('lemur') controller: 'DashboardController' }); }) - .controller('DashboardController', function ($scope, $rootScope, $filter, $location, LemurRestangular, ngTableParams) { + .controller('DashboardController', function ($scope, $rootScope, $filter, $location, LemurRestangular) { - var baseStats = LemurRestangular.all('stats'); var baseAccounts = LemurRestangular.all('accounts'); baseAccounts.getList() @@ -78,16 +77,16 @@ angular.module('lemur') LemurRestangular.all('certificates').customGET('stats', {metric: 'issuer'}) .then(function (data) { - $scope.issuers = data['items']; + $scope.issuers = data.items; }); LemurRestangular.all('certificates').customGET('stats', {metric: 'bits'}) .then(function (data) { - $scope.bits = data['items']; + $scope.bits = data.items; }); LemurRestangular.all('certificates').customGET('stats', {metric: 'not_after'}) .then(function (data) { - $scope.expiring = {labels: data['items']['labels'], values: [data['items']['values']]}; + $scope.expiring = {labels: data.items.labels, values: [data.items.values]}; }); }); diff --git a/lemur/static/app/angular/domains/services.js b/lemur/static/app/angular/domains/services.js index 3ac5579b..39c54b99 100644 --- a/lemur/static/app/angular/domains/services.js +++ b/lemur/static/app/angular/domains/services.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('lemur') .service('DomainApi', function (LemurRestangular) { return LemurRestangular.all('domains'); diff --git a/lemur/static/app/angular/elbs/services.js b/lemur/static/app/angular/elbs/services.js index 3ea3eadc..83d98dc5 100644 --- a/lemur/static/app/angular/elbs/services.js +++ b/lemur/static/app/angular/elbs/services.js @@ -1,5 +1,7 @@ +'use strict'; + angular.module('lemur') - .service('ELBApi', function (LemurRestangular, ListenerService) { + .service('ELBApi', function (LemurRestangular) { LemurRestangular.extendModel('elbs', function (obj) { return angular.extend(obj, { attachListener: function (listener) { diff --git a/lemur/static/app/angular/listeners/services.js b/lemur/static/app/angular/listeners/services.js index bd57c35f..ef141c17 100644 --- a/lemur/static/app/angular/listeners/services.js +++ b/lemur/static/app/angular/listeners/services.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('lemur') .service('ListenerApi', function (LemurRestangular) { return LemurRestangular.all('listeners'); diff --git a/lemur/static/app/angular/plugins/services.js b/lemur/static/app/angular/plugins/services.js index 2672e281..ed54bff6 100644 --- a/lemur/static/app/angular/plugins/services.js +++ b/lemur/static/app/angular/plugins/services.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('lemur') .service('PluginApi', function (LemurRestangular) { return LemurRestangular.all('plugins'); diff --git a/lemur/static/app/angular/roles/services.js b/lemur/static/app/angular/roles/services.js index 84e972c5..5b6d336b 100644 --- a/lemur/static/app/angular/roles/services.js +++ b/lemur/static/app/angular/roles/services.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('lemur') .service('RoleApi', function (LemurRestangular) { LemurRestangular.extendModel('roles', function (obj) { @@ -108,7 +110,7 @@ angular.module('lemur') role.username = response.username; } }, - function (response) { + function () { toaster.pop({ type: 'error', title: role.name, diff --git a/package.json b/package.json index 314cfb3d..f025204b 100644 --- a/package.json +++ b/package.json @@ -62,10 +62,11 @@ "pretest": "npm install && npm run build_static", "build_static": "gulp build", "prelint": "npm install", - "lint": "jshint app/", + "lint": "jshint lemur/static/app/", "test": "gulp test" }, "devDependencies": { + "jshint": "^2.8.0", "karma-chrome-launcher": "^0.2.0" } } From da004aa88fdcf6034d552a62a4951a66c9c66d97 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Tue, 21 Jul 2015 13:40:17 -0700 Subject: [PATCH 12/32] Removing a few checks, because we sadly can't fix them --- .jshintrc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.jshintrc b/.jshintrc index 40377ba2..c40849ed 100644 --- a/.jshintrc +++ b/.jshintrc @@ -3,13 +3,13 @@ "browser": true, "esnext": true, "bitwise": true, - "camelcase": true, + "camelcase": false, "curly": true, "eqeqeq": true, "immed": true, "indent": 2, "latedef": true, - "newcap": true, + "newcap": false, "noarg": true, "quotmark": "single", "regexp": true, @@ -19,6 +19,9 @@ "trailing": true, "smarttabs": true, "globals": { - "angular": false + "angular": false, + "moment": false, + "toaster": false, + "_": false } } From 8d576aa3d898d334e6105b0756109d937d81374a Mon Sep 17 00:00:00 2001 From: kevgliss Date: Wed, 22 Jul 2015 10:51:55 -0700 Subject: [PATCH 13/32] Fixing tests --- lemur/certificates/models.py | 7 ++++- lemur/destinations/service.py | 2 +- lemur/manage.py | 28 ++++++------------- lemur/tests/conftest.py | 10 +++---- lemur/tests/test_authorities.py | 10 ------- lemur/tests/test_certificates.py | 26 ++++------------- ...{test_accounts.py => test_destinations.py} | 10 +++---- 7 files changed, 29 insertions(+), 64 deletions(-) rename lemur/tests/{test_accounts.py => test_destinations.py} (92%) diff --git a/lemur/certificates/models.py b/lemur/certificates/models.py index bfe03d74..f807e1b6 100644 --- a/lemur/certificates/models.py +++ b/lemur/certificates/models.py @@ -51,6 +51,7 @@ def create_name(issuer, not_before, not_after, subject, san): # aws doesn't allow special chars except '-' disallowed_chars = ''.join(c for c in map(chr, range(256)) if not c.isalnum()) disallowed_chars = disallowed_chars.replace("-", "") + disallowed_chars = disallowed_chars.replace(".", "") temp = temp.replace('*', "WILDCARD") temp = temp.translate(None, disallowed_chars) # white space is silly too @@ -76,7 +77,7 @@ def cert_get_domains(cert): return the common name. :param cert: - :return: List of domainss + :return: List of domains """ domains = [] try: @@ -86,6 +87,7 @@ def cert_get_domains(cert): domains.append(entry) except Exception as e: current_app.logger.warning("Failed to get SubjectAltName: {0}".format(e)) + return domains @@ -122,6 +124,9 @@ def cert_is_wildcard(cert): if len(domains) == 1 and domains[0][0:1] == "*": return True + if cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)[0].value[0:1] == "*": + return True + def cert_get_bitstrength(cert): """ diff --git a/lemur/destinations/service.py b/lemur/destinations/service.py index e98e4982..38dc600f 100644 --- a/lemur/destinations/service.py +++ b/lemur/destinations/service.py @@ -37,7 +37,7 @@ def update(destination_id, label, options, description): destination = get(destination_id) destination.label = label - description.options = options + destination.options = options destination.description = description return database.update(destination) diff --git a/lemur/manage.py b/lemur/manage.py index b104f157..c939fc58 100755 --- a/lemur/manage.py +++ b/lemur/manage.py @@ -54,54 +54,42 @@ ADMINS = frozenset(['']) THREADS_PER_PAGE = 8 -############# -## General ## -############# +# General # These will need to be set to `True` if you are developing locally CORS = False debug = False -# modify this if you are not using a local database -SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur' - # this is the secret key used by flask session management SECRET_KEY = '{flask_secret_key}' # You should consider storing these separately from your config -LEMUR_SECRET_TOKEN = '{secret_token}' +LEMUR_TOKEN_SECRET = '{secret_token}' LEMUR_ENCRYPTION_KEY = '{encryption_key}' # this is a list of domains as regexes that only admins can issue LEMUR_RESTRICTED_DOMAINS = [] -################# -## Mail Server ## -################# +# Mail Server # Lemur currently only supports SES for sending email, this address # needs to be verified LEMUR_EMAIL = '' LEMUR_SECURITY_TEAM_EMAIL = [] -############# -## Logging ## -############# +# Logging LOG_LEVEL = "DEBUG" LOG_FILE = "lemur.log" -############## -## Database ## -############## +# Database -SQLALCHEMY_DATABASE_URI = '' +# modify this if you are not using a local database +SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur' -######### -## AWS ## -######### +# AWS # Lemur will need STS assume role access to every destination you want to monitor #AWS_ACCOUNT_MAPPINGS = {{ diff --git a/lemur/tests/conftest.py b/lemur/tests/conftest.py index de9b3f44..e722e695 100644 --- a/lemur/tests/conftest.py +++ b/lemur/tests/conftest.py @@ -1,3 +1,4 @@ +import os import pytest from lemur import create_app @@ -33,14 +34,11 @@ def app(): Creates a new Flask application for a test duration. Uses application factory `create_app`. """ - app = create_app() - app.config['TESTING'] = True - app.config['LEMUR_ENCRYPTION_KEY'] = 'test' - - ctx = app.app_context() + _app = create_app(os.path.dirname(os.path.realpath(__file__)) + '/conf.py') + ctx = _app.app_context() ctx.push() - yield app + yield _app ctx.pop() diff --git a/lemur/tests/test_authorities.py b/lemur/tests/test_authorities.py index 3d9becbd..5bab6124 100644 --- a/lemur/tests/test_authorities.py +++ b/lemur/tests/test_authorities.py @@ -150,13 +150,3 @@ def test_admin_certificate_authorities_get(client): assert client.get(api.url_for(CertificateAuthority, certificate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 404 -def test_admin_certificate_authorities_post(client): - assert client.post(api.url_for(CertificateAuthority, certficate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405 - - -def test_admin_certificate_authorities_put(client): - assert client.put(api.url_for(CertificateAuthority, certificate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405 - - -def test_admin_certificate_authorities_delete(client): - assert client.delete(api.url_for(CertificateAuthority, certificate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405 diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index 3d2757a4..9e573ec6 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -2,10 +2,6 @@ import pytest from lemur.certificates.views import * # noqa -def test_valid_authority(session): - assert 1 == 2 - - def test_pem_str(): from lemur.tests.certs import INTERNAL_VALID_LONG_STR assert pem_str(INTERNAL_VALID_LONG_STR, 'test') == INTERNAL_VALID_LONG_STR @@ -41,18 +37,6 @@ def test_create_basic_csr(): assert name.value in csr_config.values() -def test_import_certificate(): - assert 1 == 2 - - -def test_mint(): - assert 1 == 2 - - -def test_disassociate_aws_account(): - assert 1 == 2 - - def test_cert_get_cn(): from lemur.tests.certs import INTERNAL_VALID_LONG_CERT from lemur.certificates.models import cert_get_cn @@ -60,19 +44,19 @@ def test_cert_get_cn(): assert cert_get_cn(INTERNAL_VALID_LONG_CERT) == 'long.lived.com' -def test_cert_get_domains(): +def test_cert_get_subAltDomains(): from lemur.tests.certs import INTERNAL_VALID_SAN_CERT, INTERNAL_VALID_LONG_CERT from lemur.certificates.models import cert_get_domains - assert cert_get_domains(INTERNAL_VALID_LONG_CERT) == ['long.lived.com'] - assert cert_get_domains(INTERNAL_VALID_SAN_CERT) == ['example2.long.com', 'example3.long.com', 'san.example.com'] + assert cert_get_domains(INTERNAL_VALID_LONG_CERT) == [] + assert cert_get_domains(INTERNAL_VALID_SAN_CERT) == ['example2.long.com', 'example3.long.com'] def test_cert_is_san(): from lemur.tests.certs import INTERNAL_VALID_SAN_CERT, INTERNAL_VALID_LONG_CERT from lemur.certificates.models import cert_is_san - assert cert_is_san(INTERNAL_VALID_LONG_CERT) == False + assert cert_is_san(INTERNAL_VALID_LONG_CERT) == None assert cert_is_san(INTERNAL_VALID_SAN_CERT) == True @@ -80,7 +64,7 @@ def test_cert_is_wildcard(): from lemur.tests.certs import INTERNAL_VALID_WILDCARD_CERT, INTERNAL_VALID_LONG_CERT from lemur.certificates.models import cert_is_wildcard assert cert_is_wildcard(INTERNAL_VALID_WILDCARD_CERT) == True - assert cert_is_wildcard(INTERNAL_VALID_LONG_CERT) == False + assert cert_is_wildcard(INTERNAL_VALID_LONG_CERT) == None def test_cert_get_bitstrength(): diff --git a/lemur/tests/test_accounts.py b/lemur/tests/test_destinations.py similarity index 92% rename from lemur/tests/test_accounts.py rename to lemur/tests/test_destinations.py index f91c6525..4274bbe4 100644 --- a/lemur/tests/test_accounts.py +++ b/lemur/tests/test_destinations.py @@ -5,11 +5,11 @@ from json import dumps def test_crud(session): - destination = create('111111', 'destination1') + destination = create('testdest', 'aws-destination', {}, description='destination1') assert destination.id > 0 - destination = update(destination.id, 11111, 'destination2') - assert destination.label == 'destination2' + destination = update(destination.id, 'testdest2', {}, 'destination2') + assert destination.label == 'testdest2' assert len(get_all()) == 1 @@ -121,13 +121,13 @@ def test_admin_destinations_get(client): def test_admin_destinations_crud(client): assert client.post(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400 - data = {'destinationNumber': 111, 'label': 'test', 'comments': 'test'} + data = {'plugin': {'slug': 'aws-destination', 'pluginOptions': {}}, 'label': 'test', 'description': 'test'} resp = client.post(api.url_for(DestinationsList), data=dumps(data), content_type='application/json', headers=VALID_ADMIN_HEADER_TOKEN) assert resp.status_code == 200 assert client.get(api.url_for(Destinations, destination_id=resp.json['id']), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 resp = client.get(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN) assert resp.status_code == 200 - assert resp.json == {'items': [{'destinationNumber': 111, 'label': 'test', 'comments': 'test', 'id': 2}], 'total': 1} + assert resp.json['items'][0]['description'] == 'test' assert client.delete(api.url_for(Destinations, destination_id=2), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 resp = client.get(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN) assert resp.status_code == 200 From 412d2a1bbe3ed862bef16e1462cb364c01829420 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Wed, 22 Jul 2015 10:53:35 -0700 Subject: [PATCH 14/32] adding testing conf --- lemur/tests/conf.py | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lemur/tests/conf.py diff --git a/lemur/tests/conf.py b/lemur/tests/conf.py new file mode 100644 index 00000000..7da329af --- /dev/null +++ b/lemur/tests/conf.py @@ -0,0 +1,88 @@ + +# This is just Python which means you can inherit and tweak settings + +import os +_basedir = os.path.abspath(os.path.dirname(__file__)) + +ADMINS = frozenset(['']) + +THREADS_PER_PAGE = 8 + +############# +## General ## +############# + +# These will need to be set to `True` if you are developing locally +CORS = False +debug = False + +TESTING = True + +# this is the secret key used by flask session management +SECRET_KEY = 'I/dVhOZNSMZMqrFJa5tWli6VQccOGudKerq3eWPMSzQNmHHVhMAQfQ==' + +# You should consider storing these separately from your config +LEMUR_TOKEN_SECRET = 'test' +LEMUR_ENCRYPTION_KEY = 'jPd2xwxgVGXONqghHNq7/S761sffYSrT3UAgKwgtMxbqa0gmKYCfag==' + +# this is a list of domains as regexes that only admins can issue +LEMUR_RESTRICTED_DOMAINS = [] + +################# +## Mail Server ## +################# + +# Lemur currently only supports SES for sending email, this address +# needs to be verified +LEMUR_EMAIL = '' +LEMUR_SECURITY_TEAM_EMAIL = [] + +############# +## Logging ## +############# + +LOG_LEVEL = "DEBUG" +LOG_FILE = "lemur.log" + + +############## +## Database ## +############## + +# modify this if you are not using a local database +SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur' + + +######### +## AWS ## +######### + +# Lemur will need STS assume role access to every destination you want to monitor +#AWS_ACCOUNT_MAPPINGS = { +# '1111111111': 'myawsacount' +#} + +## This is useful if you know you only want to monitor one destination +#AWS_REGIONS = ['us-east-1'] + +#LEMUR_INSTANCE_PROFILE = 'Lemur' + +############# +## Issuers ## +############# + +# These will be dependent on which 3rd party that Lemur is +# configured to use. + +#CLOUDCA_URL = '' +#CLOUDCA_PEM_PATH = '' +#CLOUDCA_BUNDLE = '' + +# number of years to issue if not specified +#CLOUDCA_DEFAULT_VALIDITY = 2 + +#VERISIGN_URL = '' +#VERISIGN_PEM_PATH = '' +#VERISIGN_FIRST_NAME = '' +#VERISIGN_LAST_NAME = '' +#VERSIGN_EMAIL = '' From 49c742159174868adc52e8dd2d1420f2c7c2eff8 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Wed, 22 Jul 2015 20:32:29 -0700 Subject: [PATCH 15/32] More test fixes --- lemur/database.py | 5 +++-- lemur/tests/test_destinations.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lemur/database.py b/lemur/database.py index 6de3d964..c2bb8f13 100644 --- a/lemur/database.py +++ b/lemur/database.py @@ -176,8 +176,9 @@ def delete(model): :param model: """ - db.session.delete(model) - db.session.commit() + if model: + db.session.delete(model) + db.session.commit() def filter(query, model, terms): diff --git a/lemur/tests/test_destinations.py b/lemur/tests/test_destinations.py index 4274bbe4..37da1299 100644 --- a/lemur/tests/test_destinations.py +++ b/lemur/tests/test_destinations.py @@ -78,7 +78,7 @@ def test_admin_destination_put(client): def test_admin_destination_delete(client): - assert client.delete(api.url_for(Destinations, destination_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 500 + assert client.delete(api.url_for(Destinations, destination_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 def test_admin_destination_patch(client): From a4ed83cb6271eb6f588f08c2c5e6e233b9777646 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 08:52:30 -0700 Subject: [PATCH 16/32] Refactoring out challenge --- lemur/auth/views.py | 5 +++-- lemur/certificates/service.py | 13 ------------- lemur/common/utils.py | 13 +++++++++++++ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index 796b42d5..1ecbdeba 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -14,9 +14,10 @@ from flask import g, Blueprint, current_app from flask.ext.restful import reqparse, Resource, Api from flask.ext.principal import Identity, identity_changed +from lemur.common.utils import get_psuedo_random_string + from lemur.users import service as user_service from lemur.roles import service as role_service -from lemur.certificates import service as cert_service from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_key @@ -202,7 +203,7 @@ class Ping(Resource): user = user_service.create( profile['email'], - cert_service.create_challenge(), + get_psuedo_random_string(), profile['email'], True, profile.get('thumbnailPhotoUrl'), diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 75159189..4ba00e0a 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -105,7 +105,6 @@ def mint(issuer_options): csr, private_key = create_csr(issuer_options) - issuer_options['challenge'] = create_challenge() # TODO deprecate issuer_options['creator'] = g.user.email cert_body, cert_chain = issuer.create_certificate(csr, issuer_options) @@ -354,18 +353,6 @@ def create_csr(csr_config): return csr, pem -# TODO deprecate -def create_challenge(): - """ - Create a random and strongish csr challenge. - """ - challenge = ''.join(random.choice(string.ascii_uppercase) for x in range(6)) # noqa - challenge += ''.join(random.choice("~!@#$%^&*()_+") for x in range(6)) # noqa - challenge += ''.join(random.choice(string.ascii_lowercase) for x in range(6)) - challenge += ''.join(random.choice(string.digits) for x in range(6)) # noqa - return challenge - - def stats(**kwargs): """ Helper that defines some useful statistics about certifications. diff --git a/lemur/common/utils.py b/lemur/common/utils.py index e776e513..8380c579 100644 --- a/lemur/common/utils.py +++ b/lemur/common/utils.py @@ -6,6 +6,8 @@ .. moduleauthor:: Kevin Glisson """ +import string +import random from functools import wraps from flask import current_app @@ -15,6 +17,17 @@ from flask.ext.restful.reqparse import RequestParser from flask.ext.sqlalchemy import Pagination +def get_psuedo_random_string(): + """ + Create a random and strongish challenge. + """ + challenge = ''.join(random.choice(string.ascii_uppercase) for x in range(6)) # noqa + challenge += ''.join(random.choice("~!@#$%^&*()_+") for x in range(6)) # noqa + challenge += ''.join(random.choice(string.ascii_lowercase) for x in range(6)) + challenge += ''.join(random.choice(string.digits) for x in range(6)) # noqa + return challenge + + class marshal_items(object): def __init__(self, fields, envelope=None): self.fields = fields From 017eab6e39e1200111d3fca1eb6f18d268c7890c Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 08:52:56 -0700 Subject: [PATCH 17/32] Adding tests to AWS plugin --- lemur/plugins/lemur_aws/iam.py | 17 +---- lemur/plugins/lemur_aws/plugin.py | 20 ++++-- lemur/plugins/lemur_aws/tests/test_iam.py | 34 ++++++++++ lemur/plugins/lemur_verisign/plugin.py | 76 ++++++++++++++++------- lemur/tests/__init__.py | 4 ++ lemur/tests/conf.py | 44 ++++--------- lemur/tests/test_elb.py | 51 --------------- lemur/tests/test_iam.py | 35 ----------- 8 files changed, 119 insertions(+), 162 deletions(-) create mode 100644 lemur/plugins/lemur_aws/tests/test_iam.py delete mode 100644 lemur/tests/test_elb.py delete mode 100644 lemur/tests/test_iam.py diff --git a/lemur/plugins/lemur_aws/iam.py b/lemur/plugins/lemur_aws/iam.py index 63971958..9279c577 100644 --- a/lemur/plugins/lemur_aws/iam.py +++ b/lemur/plugins/lemur_aws/iam.py @@ -1,5 +1,5 @@ """ -.. module: lemur.common.services.aws.iam +.. module: lemur.plugins.lemur_aws.iam :platform: Unix :synopsis: Contains helper functions for interactive with AWS IAM Apis. :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more @@ -19,21 +19,6 @@ def get_name_from_arn(arn): return arn.split("/", 1)[1] -def ssl_split(param_string): - """ - - :param param_string: - :return: - """ - output = {} - parts = str(param_string).split("/") - for part in parts: - if "=" in part: - key, value = part.split("=", 1) - output[key] = value - return output - - def upload_cert(account_number, cert, private_key, cert_chain=None): """ Upload a certificate to AWS diff --git a/lemur/plugins/lemur_aws/plugin.py b/lemur/plugins/lemur_aws/plugin.py index 7eec91c9..72304965 100644 --- a/lemur/plugins/lemur_aws/plugin.py +++ b/lemur/plugins/lemur_aws/plugin.py @@ -58,10 +58,22 @@ class AWSSourcePlugin(SourcePlugin): author = 'Kevin Glisson' author_url = 'https://github.com/netflix/lemur' - options = { - 'accountNumber': {'type': 'int'}, - 'pollRate': {'type': 'int', 'default': '60'} - } + options = [ + { + 'name': 'accountNumber', + 'type': 'int', + 'required': True, + 'validation': '/^[0-9]{12,12}$/', + 'helpMessage': 'Must be a valid AWS account number!', + }, + { + 'name': 'pollRate', + 'type': 'int', + 'required': False, + 'helpMessage': 'Rate in seconds to poll source for new information.', + 'default': '60', + } + ] def get_certificates(self, **kwargs): certs = [] diff --git a/lemur/plugins/lemur_aws/tests/test_iam.py b/lemur/plugins/lemur_aws/tests/test_iam.py new file mode 100644 index 00000000..fd461fb2 --- /dev/null +++ b/lemur/plugins/lemur_aws/tests/test_iam.py @@ -0,0 +1,34 @@ +import pytest +from moto import mock_iam, mock_sts + +from lemur.certificates.models import Certificate + +from lemur.tests.certs import EXTERNAL_VALID_STR, PRIVATE_KEY_STR +from lemur.tests.conftest import app # noqa + + +def test_get_name_from_arn(): + from lemur.plugins.lemur_aws.iam import get_name_from_arn + arn = 'arn:aws:iam::123456789012:server-certificate/tttt2.netflixtest.net-NetflixInc-20150624-20150625' + assert get_name_from_arn(arn) == 'tttt2.netflixtest.net-NetflixInc-20150624-20150625' + + +@mock_sts() +@mock_iam() +def test_get_all_server_certs(app): + from lemur.plugins.lemur_aws.iam import upload_cert, get_all_server_certs + cert = Certificate(EXTERNAL_VALID_STR) + upload_cert('123456789012', cert, PRIVATE_KEY_STR) + certs = get_all_server_certs('123456789012') + assert len(certs) == 1 + + +@mock_sts() +@mock_iam() +def test_get_cert_from_arn(app): + from lemur.plugins.lemur_aws.iam import upload_cert, get_cert_from_arn + cert = Certificate(EXTERNAL_VALID_STR) + upload_cert('123456789012', cert, PRIVATE_KEY_STR) + body, chain = get_cert_from_arn('arn:aws:iam::123456789012:server-certificate/tttt2.netflixtest.net-NetflixInc-20150624-20150625') + assert body.replace('\n', '') == EXTERNAL_VALID_STR.replace('\n', '') + diff --git a/lemur/plugins/lemur_verisign/plugin.py b/lemur/plugins/lemur_verisign/plugin.py index ef080e83..5b2ee94a 100644 --- a/lemur/plugins/lemur_verisign/plugin.py +++ b/lemur/plugins/lemur_verisign/plugin.py @@ -16,6 +16,7 @@ from flask import current_app from lemur.plugins.bases import IssuerPlugin from lemur.plugins import lemur_verisign as verisign from lemur.plugins.lemur_verisign import constants +from lemur.common.utils import get_psuedo_random_string # https://support.venafi.com/entries/66445046-Info-VeriSign-Error-Codes @@ -58,9 +59,57 @@ VERISIGN_ERRORS = { } +def process_options(options): + """ + Processes and maps the incoming issuer options to fields/options that + verisign understands + + :param options: + :return: dict or valid verisign options + """ + data = { + 'challenge': get_psuedo_random_string(), + 'serverType': 'Apache', + 'certProductType': 'Server', + 'firstName': current_app.config.get("VERISIGN_FIRST_NAME"), + 'lastName': current_app.config.get("VERISIGN_LAST_NAME"), + 'signatureAlgorithm': 'sha256WithRSAEncryption', + 'email': current_app.config.get("VERISIGN_EMAIL") + } + + if options.get('validityEnd'): + end_date, period = get_default_issuance(options) + data['specificEndDate'] = end_date + data['validityPeriod'] = period + + return data + + +def get_default_issuance(options): + """ + Gets the default time range for certificates + + :param options: + :return: + """ + specific_end_date = arrow.get(options['validityEnd']).replace(days=-1).format("MM/DD/YYYY") + + now = arrow.utcnow() + then = arrow.get(options['validityEnd']) + + if then < now.replace(years=+1): + validity_period = '1Y' + elif then < now.replace(years=+2): + validity_period = '2Y' + else: + raise Exception("Verisign issued certificates cannot exceed two years in validity") + + return specific_end_date, validity_period + + def handle_response(content): """ - Helper function that helps with parsing responses from the Verisign API. + Helper function for parsing responses from the Verisign API. :param content: :return: :raise Exception: """ @@ -99,29 +148,8 @@ class VerisignIssuerPlugin(IssuerPlugin): """ url = current_app.config.get("VERISIGN_URL") + '/enroll' - data = { - 'csr': csr, - 'challenge': issuer_options['challenge'], - 'serverType': 'Apache', - 'certProductType': 'Server', - 'firstName': current_app.config.get("VERISIGN_FIRST_NAME"), - 'lastName': current_app.config.get("VERISIGN_LAST_NAME"), - 'signatureAlgorithm': 'sha256WithRSAEncryption', - 'email': current_app.config.get("VERISIGN_EMAIL") - } - - if issuer_options.get('validityEnd'): - data['specificEndDate'] = arrow.get(issuer_options['validityEnd']).replace(days=-1).format("MM/DD/YYYY") - - now = arrow.utcnow() - then = arrow.get(issuer_options['validityEnd']) - - if then < now.replace(years=+1): - data['validityPeriod'] = '1Y' - elif then < now.replace(years=+2): - data['validityPeriod'] = '2Y' - else: - raise Exception("Verisign issued certificates cannot exceed two years in validity") + data = process_options(issuer_options) + data['csr'] = csr current_app.logger.info("Requesting a new verisign certificate: {0}".format(data)) diff --git a/lemur/tests/__init__.py b/lemur/tests/__init__.py index 27dc8f42..c2cb93b4 100644 --- a/lemur/tests/__init__.py +++ b/lemur/tests/__init__.py @@ -3,3 +3,7 @@ import unittest class LemurTestCase(unittest.TestCase): pass + + +class LemurPluginTestCase(LemurTestCase): + pass diff --git a/lemur/tests/conf.py b/lemur/tests/conf.py index 7da329af..98b518c7 100644 --- a/lemur/tests/conf.py +++ b/lemur/tests/conf.py @@ -8,9 +8,7 @@ ADMINS = frozenset(['']) THREADS_PER_PAGE = 8 -############# -## General ## -############# +# General # These will need to be set to `True` if you are developing locally CORS = False @@ -28,48 +26,30 @@ LEMUR_ENCRYPTION_KEY = 'jPd2xwxgVGXONqghHNq7/S761sffYSrT3UAgKwgtMxbqa0gmKYCfag== # this is a list of domains as regexes that only admins can issue LEMUR_RESTRICTED_DOMAINS = [] -################# -## Mail Server ## -################# +# Mail Server # Lemur currently only supports SES for sending email, this address # needs to be verified LEMUR_EMAIL = '' LEMUR_SECURITY_TEAM_EMAIL = [] -############# -## Logging ## -############# +# Logging LOG_LEVEL = "DEBUG" LOG_FILE = "lemur.log" -############## -## Database ## -############## +# Database # modify this if you are not using a local database SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur' -######### -## AWS ## -######### +# AWS -# Lemur will need STS assume role access to every destination you want to monitor -#AWS_ACCOUNT_MAPPINGS = { -# '1111111111': 'myawsacount' -#} +LEMUR_INSTANCE_PROFILE = 'Lemur' -## This is useful if you know you only want to monitor one destination -#AWS_REGIONS = ['us-east-1'] - -#LEMUR_INSTANCE_PROFILE = 'Lemur' - -############# -## Issuers ## -############# +# Issuers # These will be dependent on which 3rd party that Lemur is # configured to use. @@ -81,8 +61,8 @@ SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur' # number of years to issue if not specified #CLOUDCA_DEFAULT_VALIDITY = 2 -#VERISIGN_URL = '' -#VERISIGN_PEM_PATH = '' -#VERISIGN_FIRST_NAME = '' -#VERISIGN_LAST_NAME = '' -#VERSIGN_EMAIL = '' +VERISIGN_URL = 'http://example.com' +VERISIGN_PEM_PATH = '~/' +VERISIGN_FIRST_NAME = 'Jim' +VERISIGN_LAST_NAME = 'Bob' +VERSIGN_EMAIL = 'jim@example.com' diff --git a/lemur/tests/test_elb.py b/lemur/tests/test_elb.py deleted file mode 100644 index e336aaf2..00000000 --- a/lemur/tests/test_elb.py +++ /dev/null @@ -1,51 +0,0 @@ -# import boto -# from lemur.tests import LemurTestCase - -# from moto import mock_elb, mock_sts - - -# class ELBTestCase(LemurTestCase): -# @mock_sts -# @mock_elb -# def test_add_listener(self): -# from lemur.common.services.aws.elb import create_new_listeners -# conn = boto.connect_elb() -# zones = ['us-east-1a', 'us-east-1b'] -# ports = [(80, 8080, 'http')] -# conn.create_load_balancer('my-lb', zones, ports) -# create_new_listeners('111', 'us-east-1', 'my-lb', listeners=[('443', '80', 'HTTP')]) -# balancer = conn.get_all_load_balancers()[0] -# self.assertEqual(balancer.name, "my-lb") -# self.assertEqual(len(balancer.listeners), 2) -# -# @mock_sts -# @mock_elb -# def test_update_listener(self): -# from lemur.common.services.aws.elb import update_listeners -# conn = boto.connect_elb() -# zones = ['us-east-1a', 'us-east-1b'] -# ports = [(80, 8080, 'http')] -# conn.create_load_balancer('my-lb', zones, ports) -# update_listeners('111', 'us-east-1', 'my-lb', listeners=[('80', '7001', 'http')]) -# balancer = conn.get_all_load_balancers()[0] -# listener = balancer.listeners[0] -# self.assertEqual(listener.load_balancer_port, 80) -# self.assertEqual(listener.instance_port, 7001) -# self.assertEqual(listener.protocol, "HTTP") -# -# @mock_sts -# @mock_elb -# def test_set_certificate(self): -# from lemur.common.services.aws.elb import attach_certificate -# conn = boto.connect_elb() -# zones = ['us-east-1a', 'us-east-1b'] -# ports = [(443, 7001, 'https', 'sslcert')] -# conn.create_load_balancer('my-lb', zones, ports) -# attach_certificate('1111', 'us-east-1', 'my-lb', 443, 'somecert') -# balancer = conn.get_all_load_balancers()[0] -# listener = balancer.listeners[0] -# self.assertEqual(listener.load_balancer_port, 443) -# self.assertEqual(listener.instance_port, 7001) -# self.assertEqual(listener.protocol, "HTTPS") -# self.assertEqual(listener.ssl_certificate_id, 'somecert') -# diff --git a/lemur/tests/test_iam.py b/lemur/tests/test_iam.py deleted file mode 100644 index 89e1a6fc..00000000 --- a/lemur/tests/test_iam.py +++ /dev/null @@ -1,35 +0,0 @@ -# from lemur.tests import LemurTestCase - -# from lemur.certificates.models import Certificate - -# from moto import mock_iam, mock_sts - - -# class IAMTestCase(LemurTestCase): -# @mock_sts -# @mock_iam -# def test_get_all_server_certs(self): -# from lemur.common.services.aws.iam import upload_cert, get_all_server_certs -# cert = Certificate(TEST_CERT) -# upload_cert('1111', cert, TEST_KEY) -# certs = get_all_server_certs('1111') -# self.assertEquals(len(certs), 1) -# -# @mock_sts -# @mock_iam -# def test_get_server_cert(self): -# from lemur.common.services.aws.iam import upload_cert, get_cert_from_arn -# cert = Certificate(TEST_CERT) -# upload_cert('1111', cert, TEST_KEY) -# body, chain = get_cert_from_arn('arn:aws:iam::123456789012:server-certificate/AHB-dfdsflkj.net-NetflixInc-20140525-20150525') -# self.assertTrue(body) -# -# @mock_sts -# @mock_iam -# def test_upload_server_cert(self): -# from lemur.common.services.aws.iam import upload_cert -# cert = Certificate(TEST_CERT) -# response = upload_cert('1111', cert, TEST_KEY) -# self.assertEquals(response['upload_server_certificate_response']['upload_server_certificate_result']['server_certificate_metadata']['server_certificate_name'], 'AHB-dfdsflkj.net-NetflixInc-20140525-20150525') -# -# From c02390d63b6e1f033195bc9d5eefa78daea7784d Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 09:08:07 -0700 Subject: [PATCH 18/32] PEP8 --- lemur/certificates/service.py | 2 -- lemur/decorators.py | 2 +- lemur/plugins/lemur_aws/tests/test_iam.py | 3 --- lemur/tests/conf.py | 8 ++++---- lemur/tests/test_authorities.py | 2 -- 5 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 4ba00e0a..f1997344 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -6,8 +6,6 @@ .. moduleauthor:: Kevin Glisson """ import arrow -import string -import random from sqlalchemy import func, or_ from flask import g, current_app diff --git a/lemur/decorators.py b/lemur/decorators.py index bb37dcf4..70f8de6a 100644 --- a/lemur/decorators.py +++ b/lemur/decorators.py @@ -12,7 +12,7 @@ from functools import update_wrapper # this is only used for dev def crossdomain(origin=None, methods=None, headers=None, max_age=21600, attach_to_all=True, - automatic_options=True): + automatic_options=True): # pragma: no cover if methods is not None: methods = ', '.join(sorted(x.upper() for x in methods)) diff --git a/lemur/plugins/lemur_aws/tests/test_iam.py b/lemur/plugins/lemur_aws/tests/test_iam.py index fd461fb2..bc86feb7 100644 --- a/lemur/plugins/lemur_aws/tests/test_iam.py +++ b/lemur/plugins/lemur_aws/tests/test_iam.py @@ -1,10 +1,8 @@ -import pytest from moto import mock_iam, mock_sts from lemur.certificates.models import Certificate from lemur.tests.certs import EXTERNAL_VALID_STR, PRIVATE_KEY_STR -from lemur.tests.conftest import app # noqa def test_get_name_from_arn(): @@ -31,4 +29,3 @@ def test_get_cert_from_arn(app): upload_cert('123456789012', cert, PRIVATE_KEY_STR) body, chain = get_cert_from_arn('arn:aws:iam::123456789012:server-certificate/tttt2.netflixtest.net-NetflixInc-20150624-20150625') assert body.replace('\n', '') == EXTERNAL_VALID_STR.replace('\n', '') - diff --git a/lemur/tests/conf.py b/lemur/tests/conf.py index 98b518c7..30a0174f 100644 --- a/lemur/tests/conf.py +++ b/lemur/tests/conf.py @@ -54,12 +54,12 @@ LEMUR_INSTANCE_PROFILE = 'Lemur' # These will be dependent on which 3rd party that Lemur is # configured to use. -#CLOUDCA_URL = '' -#CLOUDCA_PEM_PATH = '' -#CLOUDCA_BUNDLE = '' +# CLOUDCA_URL = '' +# CLOUDCA_PEM_PATH = '' +# CLOUDCA_BUNDLE = '' # number of years to issue if not specified -#CLOUDCA_DEFAULT_VALIDITY = 2 +# CLOUDCA_DEFAULT_VALIDITY = 2 VERISIGN_URL = 'http://example.com' VERISIGN_PEM_PATH = '~/' diff --git a/lemur/tests/test_authorities.py b/lemur/tests/test_authorities.py index 5bab6124..8e29dbd2 100644 --- a/lemur/tests/test_authorities.py +++ b/lemur/tests/test_authorities.py @@ -148,5 +148,3 @@ def test_admin_authorities_delete(client): def test_admin_certificate_authorities_get(client): assert client.get(api.url_for(CertificateAuthority, certificate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 404 - - From fe136a89d41760fbb5cd1041b66f73a048830494 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 09:24:17 -0700 Subject: [PATCH 19/32] Ensuring a user exists for the postgres tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9e79b3ca..1be110c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ env: install: - make develop dev-postgres before_script: - - psql -c 'create database lemur;' -U postgres + - psql -c 'create database lemur; create user lemur with password 'lemur;' -U postgres - npm install -g bower script: - make lint From 722d65f276a65160052195483105fbc0726fc1b8 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 09:34:16 -0700 Subject: [PATCH 20/32] Fixing quoted string --- .travis.yml | 2 +- hooks/pre-commit | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 hooks/pre-commit diff --git a/.travis.yml b/.travis.yml index 1be110c8..3b00d400 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ env: install: - make develop dev-postgres before_script: - - psql -c 'create database lemur; create user lemur with password 'lemur;' -U postgres + - psql -c "create database lemur; create user lemur with password 'lemur;' -U postgres" - npm install -g bower script: - make lint diff --git a/hooks/pre-commit b/hooks/pre-commit old mode 100644 new mode 100755 From 378b83307d39ac82fd3afeba233c0b27d0e464f2 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 09:47:50 -0700 Subject: [PATCH 21/32] fixing quote for realz --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3b00d400..fd3e32cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ env: install: - make develop dev-postgres before_script: - - psql -c "create database lemur; create user lemur with password 'lemur;' -U postgres" + - psql -c "create database lemur; create user lemur with password 'lemur;'" -U postgres - npm install -g bower script: - make lint From d850d677da4954f0e1f2d6340fc92e4cee9e36be Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 09:54:38 -0700 Subject: [PATCH 22/32] Fixing postgres command --- .travis.yml | 3 ++- hooks/pre-commit | 10 +--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd3e32cf..360f6131 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,8 @@ env: install: - make develop dev-postgres before_script: - - psql -c "create database lemur; create user lemur with password 'lemur;'" -U postgres + - psql -c "create database lemur;" -U postgres + - psql -c "create user lemur with password 'lemur;'" -U postgres - npm install -g bower script: - make lint diff --git a/hooks/pre-commit b/hooks/pre-commit index b41d5f35..5925a453 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -29,14 +29,6 @@ def py_lint(files_modified): return report.total_errors != 0 -def js_lint(files_modified): - has_errors = False - if os.system('node_modules/.bin/jshint src/sentry'): - has_errors = True - - return has_errors - - def main(): from flake8.hooks import run @@ -46,7 +38,7 @@ def main(): files_modified = filter(lambda x: os.path.exists(x), files_modified) - if any((py_lint(files_modified), js_lint(files_modified))): + if py_lint(files_modified): return 1 return 0 From 927b57abbaf3adef3b2abd0c65bb5a48dc901f8e Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 10:01:18 -0700 Subject: [PATCH 23/32] Specifying newer postgres --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 360f6131..bac7281f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: python -services: - - postgresql +addons: + postgresql: "9.4" python: - "2.7" cache: From 66a4212d2a0bfbffce9262701d632b268e627aed Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 10:22:16 -0700 Subject: [PATCH 24/32] Specifying dev version of cryptography to get support for CSR building --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 411a040c..3a56e73b 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ from subprocess import check_output ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__))) -install_requires=[ +install_requires = [ 'Flask>=0.10.1', 'Flask-RESTful>=0.3.3', 'Flask-SQLAlchemy>=1.0.5', @@ -61,6 +61,7 @@ dev_requires = [ 'flake8>=2.0,<2.1', ] + class SmartInstall(install): """ Installs Lemur into the Python environment. @@ -75,6 +76,7 @@ class SmartInstall(install): self.run_command('build_static') install.run(self) + class DevelopWithBuildStatic(develop): def install_for_development(self): self.run_command('build_static') @@ -137,6 +139,9 @@ setup( 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin' ], }, + dependency_links=[ + "git+ssh://git@github.com/pyca/cryptography.git@1.0.dev1#egg=cryptography-1.0.dev1" + ], classifiers=[ 'Framework :: Flask', 'Intended Audience :: Developers', From 9bc292c107dd801ae0003a95e498c6412b2d8474 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 10:34:47 -0700 Subject: [PATCH 25/32] Trying to get dep links to be recognized --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3a56e73b..cec4ad78 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ install_requires = [ 'six>=1.9.0', 'gunicorn>=19.3.0', 'pycrypto>=2.6.1', - 'cryptography>=0.9', + 'cryptography>=1.0dev', 'pyopenssl>=0.15.1', 'pyjwt>=1.0.1', 'xmltodict>=0.9.2' From 919a8e231d28c364454b9864a7e73ca8ca1602c3 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 10:58:10 -0700 Subject: [PATCH 26/32] Hoping cache is messing us up --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index bac7281f..20ed7066 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,6 @@ python: cache: directories: - node_modules - - .pip_download_cache - - "$HOME/virtualenv/python2.7.9" -env: - global: - - PIP_DOWNLOAD_CACHE=".pip_download_cache" install: - make develop dev-postgres before_script: From 66df3d4291bc689fd47cc9885415ae73bb0951a0 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 12:16:56 -0700 Subject: [PATCH 27/32] Moving the temporary asset to the makefile instead of setup.py --- Makefile | 2 ++ setup.cfg | 2 +- setup.py | 3 --- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 03369342..399ac942 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ develop: update-submodules setup-git npm install pip install "setuptools>=0.9.8" # order matters here, base package must install first + # this is temporary until the version we need is released + pip install -e git+https://git@github.com/pyca/cryptography.git@1.0.dev1#egg=cryptography-1.0.dev1 pip install -e . pip install "file://`pwd`#egg=lemur[dev]" pip install "file://`pwd`#egg=lemur[tests]" diff --git a/setup.cfg b/setup.cfg index a1e4f550..fe08c7bf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,4 +9,4 @@ max-line-length = 100 exclude = .tox,.git,*/migrations/*,lemur/static/*,docs/* [wheel] -universal = 1 \ No newline at end of file +universal = 1 diff --git a/setup.py b/setup.py index cec4ad78..5fe92052 100644 --- a/setup.py +++ b/setup.py @@ -139,9 +139,6 @@ setup( 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin' ], }, - dependency_links=[ - "git+ssh://git@github.com/pyca/cryptography.git@1.0.dev1#egg=cryptography-1.0.dev1" - ], classifiers=[ 'Framework :: Flask', 'Intended Audience :: Developers', From d16d51c47db066ac4cac6f831088e8e66fd78ef0 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 12:20:17 -0700 Subject: [PATCH 28/32] Fixing url format --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 399ac942..dd2c2695 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ develop: update-submodules setup-git pip install "setuptools>=0.9.8" # order matters here, base package must install first # this is temporary until the version we need is released - pip install -e git+https://git@github.com/pyca/cryptography.git@1.0.dev1#egg=cryptography-1.0.dev1 + pip install -e 'git+https://git@github.com/pyca/cryptography.git#egg=cryptography-1.0.dev1' pip install -e . pip install "file://`pwd`#egg=lemur[dev]" pip install "file://`pwd`#egg=lemur[tests]" From e9b810229b6135c9c3549a03ae96494590b52d72 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 12:26:18 -0700 Subject: [PATCH 29/32] Adding back caches --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 20ed7066..bac7281f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,11 @@ python: cache: directories: - node_modules + - .pip_download_cache + - "$HOME/virtualenv/python2.7.9" +env: + global: + - PIP_DOWNLOAD_CACHE=".pip_download_cache" install: - make develop dev-postgres before_script: From d1bb635fecd0695ebc3cd62b2c1f0102c5857b97 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 12:32:13 -0700 Subject: [PATCH 30/32] Removing installing lemur twice --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bac7281f..d4d11eaa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,13 +13,12 @@ env: global: - PIP_DOWNLOAD_CACHE=".pip_download_cache" install: - - make develop dev-postgres + - make dev-postgres before_script: - psql -c "create database lemur;" -U postgres - psql -c "create user lemur with password 'lemur;'" -U postgres - npm install -g bower script: - - make lint - make test notifications: From d51517268a763b25dcf5429c4b63591487506f85 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 12:47:43 -0700 Subject: [PATCH 31/32] Trying to pin test requirements to fix weird testing issue --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 5fe92052..5c725872 100644 --- a/setup.py +++ b/setup.py @@ -46,10 +46,10 @@ install_requires = [ tests_require = [ 'pyflakes', - 'moto', - 'nose', - 'pytest', - 'pytest-flask' + 'moto=0.4.6', + 'nose=1.3.7', + 'pytest=2.7.2', + 'pytest-flask=0.8.1' ] docs_require = [ From 3adae27a87e672c00d944f2d197f46f00d830b58 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Thu, 23 Jul 2015 13:01:45 -0700 Subject: [PATCH 32/32] Fixing pinning --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 5c725872..2caf245f 100644 --- a/setup.py +++ b/setup.py @@ -46,10 +46,10 @@ install_requires = [ tests_require = [ 'pyflakes', - 'moto=0.4.6', - 'nose=1.3.7', - 'pytest=2.7.2', - 'pytest-flask=0.8.1' + 'moto==0.4.6', + 'nose==1.3.7', + 'pytest==2.7.2', + 'pytest-flask==0.8.1' ] docs_require = [