Pleasing the PEP8 gods

This commit is contained in:
kevgliss 2015-07-21 13:06:13 -07:00
parent 0082b163d2
commit c75e20a1ea
78 changed files with 170 additions and 308 deletions

View File

@ -24,4 +24,4 @@ module.exports = function (config) {
//...
}
});
}
};

View File

@ -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;
});

View File

@ -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

View File

@ -4,7 +4,7 @@
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
#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))

View File

@ -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__()

View File

@ -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')

View File

@ -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)

View File

@ -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)

View File

@ -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'])

View File

@ -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}

View File

@ -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}

View File

@ -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

View File

@ -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)
os.remove(file_path)

View File

@ -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')

View File

@ -10,6 +10,7 @@ from flask import Blueprint
mod = Blueprint('healthCheck', __name__)
@mod.route('/healthcheck')
def health():
return 'ok'
return 'ok'

View File

@ -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
return results

View File

@ -6,8 +6,8 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
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')

View File

@ -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

View File

@ -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}"

View File

@ -9,13 +9,11 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
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)

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -107,4 +107,3 @@ def render(args):
query = database.sort(query, Destination, sort_by, sort_dir)
return database.paginate(query, page, count)

View File

@ -229,7 +229,6 @@ class Destinations(AuthenticatedResource):
return {'result': True}
class CertificateDestinations(AuthenticatedResource):
""" Defines the 'certificate/<int:certificate_id/destinations'' endpoint """
def __init__(self):
@ -274,5 +273,5 @@ class CertificateDestinations(AuthenticatedResource):
api.add_resource(DestinationsList, '/destinations', endpoint='destinations')
api.add_resource(Destinations, '/destinations/<int:destination_id>', endpoint='account')
api.add_resource(CertificateDestinations, '/certificates/<int:certificate_id>/destinations', endpoint='certificateDestinations')
api.add_resource(CertificateDestinations, '/certificates/<int:certificate_id>/destinations',
endpoint='certificateDestinations')

View File

@ -24,4 +24,3 @@ class Domain(db.Model):
blob = self.as_dict()
blob['certificates'] = [x.id for x in self.certificate]
return blob

View File

@ -61,4 +61,3 @@ def render(args):
query = database.sort(query, Domain, sort_by, sort_dir)
return database.paginate(query, page, count)

View File

@ -6,7 +6,7 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
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))

View File

@ -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

View File

@ -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 <kglisson@netflix.com>
"""
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))

View File

@ -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()

View File

@ -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:

View File

@ -40,4 +40,3 @@ class Listener(db.Model):
blob = self.as_dict()
del blob['date_created']
return blob

View File

@ -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

View File

@ -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")

View File

@ -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'))
)

View File

@ -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())

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -8,6 +8,7 @@
"""
from threading import local
# stolen from https://github.com/getsentry/sentry/
class PluginMount(type):
def __new__(cls, name, bases, attrs):

View File

@ -1,3 +1,3 @@
from .destination import DestinationPlugin # NOQA
from .issuer import IssuerPlugin # NOQA
from .source import SourcePlugin
from .destination import DestinationPlugin # noqa
from .issuer import IssuerPlugin # noqa
from .source import SourcePlugin # noqa

View File

@ -8,9 +8,9 @@
"""
from lemur.plugins.base import Plugin
class DestinationPlugin(Plugin):
type = 'destination'
def upload(self):
raise NotImplemented

View File

@ -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

View File

@ -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 {}

View File

@ -2,4 +2,4 @@ try:
VERSION = __import__('pkg_resources') \
.get_distribution(__name__).version
except Exception, e:
VERSION = 'unknown'
VERSION = 'unknown'

View File

@ -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)

View File

@ -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),

View File

@ -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)

View File

@ -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)

View File

@ -2,4 +2,4 @@ try:
VERSION = __import__('pkg_resources') \
.get_distribution(__name__).version
except Exception, e:
VERSION = 'unknown'
VERSION = 'unknown'

View File

@ -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 = []

View File

@ -2,4 +2,4 @@ try:
VERSION = __import__('pkg_resources') \
.get_distribution(__name__).version
except Exception, e:
VERSION = 'unknown'
VERSION = 'unknown'

View File

@ -55,4 +55,3 @@ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
"""

View File

@ -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']

View File

@ -137,4 +137,3 @@ class PluginsTypeList(AuthenticatedResource):
api.add_resource(PluginsList, '/plugins', endpoint='plugins')
api.add_resource(PluginsTypeList, '/plugins/<plugin_type>', endpoint='pluginType')

View File

@ -36,4 +36,3 @@ class Role(db.Model):
def serialize(self):
blob = self.as_dict()
return blob

View File

@ -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)

View File

@ -41,7 +41,7 @@ angular.module('lemur')
});
}
);
}
};
AuthenticationService.logout = function () {
if (!$auth.isAuthenticated()) {

View File

@ -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;
};

View File

@ -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;
};

View File

@ -32,7 +32,7 @@ angular.module('lemur')
DestinationService.update(destination).then(function () {
$modalInstance.close();
});
}
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');

View File

@ -18,7 +18,7 @@ angular.module('lemur')
UserService.update(user).then(function () {
$modalInstance.close();
});
}
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');

View File

@ -1,4 +1,5 @@
import unittest
class LemurTestCase(unittest.TestCase):
pass

View File

@ -218,4 +218,4 @@ CSR_CONFIG = """
[alt_names]
# Put your SANs here
"""
"""

View File

@ -73,4 +73,3 @@ def session(db, request):
@pytest.yield_fixture(scope="function")
def client(app, session, client):
yield client

View File

@ -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)

View File

@ -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
#

View File

@ -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

View File

@ -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}
"""

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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
#

View File

@ -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):

View File

@ -84,5 +84,3 @@ class User(db.Model):
listen(User, 'before_insert', hash_password)

View File

@ -145,5 +145,3 @@ def render(args):
query = database.sort(query, User, sort_by, sort_dir)
return database.paginate(query, page, count)