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(c.green + '-------------------------------------------' + c.reset);
console.log(Object.keys(gulp.tasks).sort().join('\n')); console.log(Object.keys(gulp.tasks).sort().join('\n'));
console.log(''); console.log('');
return;
}); });

View File

@ -36,6 +36,7 @@ LEMUR_BLUEPRINTS = (
plugins_bp, plugins_bp,
) )
def create_app(config=None): def create_app(config=None):
app = factory.create_app(app_name=__name__, blueprints=LEMUR_BLUEPRINTS, config=config) app = factory.create_app(app_name=__name__, blueprints=LEMUR_BLUEPRINTS, config=config)
configure_hook(app) configure_hook(app)
@ -61,4 +62,3 @@ def configure_hook(app):
response = {'message': 'You are not allow to access this resource'} response = {'message': 'You are not allow to access this resource'}
response.status_code = 403 response.status_code = 403
return response return response

View File

@ -4,7 +4,7 @@
:license: Apache, see LICENSE for more details. :license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
#def analyze(endpoints, truststores): # def analyze(endpoints, truststores):
# results = {"headings": ["Endpoint"], # results = {"headings": ["Endpoint"],
# "results": [], # "results": [],
# "time": datetime.now().strftime("#Y%m%d %H:%M:%S")} # "time": datetime.now().strftime("#Y%m%d %H:%M:%S")}
@ -37,7 +37,9 @@
# log.debug(e) # log.debug(e)
# if 'hostname' in str(e): # if 'hostname' in str(e):
# tests.append('pass') # 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): # elif 'certificate verify failed' in str(e):
# tests.append('fail') # tests.append('fail')
# result['details'].append("{}: This test failed to verify the SSL certificate".format(region)) # 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.users import service as user_service
from lemur.auth.permissions import CertificateOwnerNeed, CertificateCreatorNeed, \ from lemur.auth.permissions import CertificateOwnerNeed, CertificateCreatorNeed, \
AuthorityCreatorNeed, AuthorityOwnerNeed, ViewRoleCredentialsNeed AuthorityCreatorNeed, ViewRoleCredentialsNeed
def base64url_decode(data): def base64url_decode(data):
@ -143,7 +143,6 @@ def fetch_token_header(token):
raise jwt.DecodeError('Invalid header padding') raise jwt.DecodeError('Invalid header padding')
@identity_loaded.connect @identity_loaded.connect
def on_identity_loaded(sender, identity): def on_identity_loaded(sender, identity):
""" """
@ -187,5 +186,3 @@ class AuthenticatedResource(Resource):
def __init__(self): def __init__(self):
super(AuthenticatedResource, self).__init__() super(AuthenticatedResource, self).__init__()

View File

@ -9,16 +9,15 @@ import jwt
import base64 import base64
import requests 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.restful import reqparse, Resource, Api
from flask.ext.principal import Identity, identity_changed 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.users import service as user_service
from lemur.roles import service as role_service from lemur.roles import service as role_service
from lemur.certificates import service as cert_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__) mod = Blueprint('auth', __name__)
@ -222,7 +221,7 @@ class Ping(Resource):
profile['email'], profile['email'],
profile['email'], profile['email'],
True, True,
profile.get('thumbnailPhotoUrl'), # incase profile isn't google+ enabled profile.get('thumbnailPhotoUrl'), # Encase profile isn't google+ enabled
roles roles
) )
@ -234,5 +233,3 @@ class Ping(Resource):
api.add_resource(Login, '/auth/login', endpoint='login') api.add_resource(Login, '/auth/login', endpoint='login')
api.add_resource(Ping, '/auth/ping', endpoint='ping') 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 from lemur.plugins.base import plugins
def update(authority_id, active=None, roles=None): def update(authority_id, active=None, roles=None):
""" """
Update a an authority with new values. Update a an authority with new values.
@ -30,7 +31,7 @@ def update(authority_id, active=None, roles=None):
""" """
authority = get(authority_id) authority = get(authority_id)
if roles: if roles:
authority = database.update_list(authority, 'roles', Role, roles) authority = database.update_list(authority, 'roles', Role, roles)
if active: if active:
authority.active = active authority.active = active
@ -62,9 +63,9 @@ def create(kwargs):
for r in issuer_roles: for r in issuer_roles:
role = role_service.create( role = role_service.create(
r['name'], r['name'],
password=r['password'], password=r['password'],
description="{0} auto generated role".format(kwargs.get('pluginName')), description="{0} auto generated role".format(kwargs.get('pluginName')),
username=r['username']) username=r['username'])
# the user creating the authority should be able to administer it # the user creating the authority should be able to administer it
if role.username == 'admin': if role.username == 'admin':
@ -132,7 +133,7 @@ def get_authority_role(ca_name):
""" """
if g.current_user.is_admin: if g.current_user.is_admin:
authority = get_by_name(ca_name) 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] return authority.roles[0]
else: else:
for role in g.current_user.roles: for role in g.current_user.roles:
@ -156,7 +157,7 @@ def render(args):
if filt: if filt:
terms = filt.split(';') 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]) query = query.filter(Authority.active == terms[1])
else: else:
query = database.filter(query, Authority, terms) 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('caDescription', type=str, location='json', required=False)
self.reqparse.add_argument('ownerEmail', type=str, location='json', required=True) 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('caDN', type=dict, location='json', required=False)
self.reqparse.add_argument('validityStart', 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('validityEnd', type=str, location='json', required=False) # TODO validate
self.reqparse.add_argument('extensions', type=dict, location='json', required=False) 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('pluginName', type=str, location='json', required=True)
self.reqparse.add_argument('caType', type=str, location='json', required=False) self.reqparse.add_argument('caType', type=str, location='json', required=False)

View File

@ -53,6 +53,7 @@ class UnableToCreateCSR(LemurException):
def __str__(self): def __str__(self):
return repr(self.data['message']) return repr(self.data['message'])
class UnableToCreatePrivateKey(LemurException): class UnableToCreatePrivateKey(LemurException):
def __init__(self): def __init__(self):
self.code = 500 self.code = 500
@ -63,6 +64,7 @@ class UnableToCreatePrivateKey(LemurException):
def __str__(self): def __str__(self):
return repr(self.data['message']) return repr(self.data['message'])
class MissingFiles(LemurException): class MissingFiles(LemurException):
def __init__(self, path): def __init__(self, path):
self.code = 500 self.code = 500
@ -84,4 +86,3 @@ class NoPersistanceFound(LemurException):
def __str__(self): def __str__(self):
return repr(self.data['message']) return repr(self.data['message'])

View File

@ -21,7 +21,7 @@ from lemur.database import db
from lemur.domains.models import Domain 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 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: if len(cert_get_domains(cert)) > 1:
return True return True
def cert_is_wildcard(cert): def cert_is_wildcard(cert):
""" """
Determines if certificate is a wildcard certificate. Determines if certificate is a wildcard certificate.
@ -197,8 +198,8 @@ class Certificate(db.Model):
owner = Column(String(128)) owner = Column(String(128))
body = Column(Text()) body = Column(Text())
private_key = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY'))) private_key = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY')))
challenge = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY'))) # TODO deprecate challenge = Column(EncryptedType(String, os.environ.get('LEMUR_ENCRYPTION_KEY'))) # TODO deprecate
csr_config = Column(Text()) # TODO deprecate csr_config = Column(Text()) # TODO deprecate
status = Column(String(128)) status = Column(String(128))
deleted = Column(Boolean, index=True) deleted = Column(Boolean, index=True)
name = Column(String(128)) name = Column(String(128))
@ -266,4 +267,3 @@ class Certificate(db.Model):
def as_dict(self): def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns} 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 from cryptography.hazmat.primitives.asymmetric import rsa
def get(cert_id): def get(cert_id):
""" """
Retrieves certificate by it's ID. Retrieves certificate by it's ID.
@ -106,7 +105,7 @@ def mint(issuer_options):
csr, private_key = create_csr(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 issuer_options['creator'] = g.user.email
cert_body, cert_chain = issuer.create_certificate(csr, issuer_options) cert_body, cert_chain = issuer.create_certificate(csr, issuer_options)
@ -212,8 +211,8 @@ def render(args):
time_range = args.pop('time_range') time_range = args.pop('time_range')
destination_id = args.pop('destination_id') destination_id = args.pop('destination_id')
show = args.pop('show') show = args.pop('show')
owner = args.pop('owner') # owner = args.pop('owner')
creator = args.pop('creator') # TODO we should enabling filtering by owner # creator = args.pop('creator') # TODO we should enabling filtering by owner
filt = args.pop('filter') filt = args.pop('filter')
@ -235,7 +234,7 @@ def render(args):
if 'destination' in terms: if 'destination' in terms:
query = query.filter(Certificate.destinations.any(Destination.id == terms[1])) 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]) query = query.filter(Certificate.active == terms[1])
else: else:
query = database.filter(query, Certificate, terms) query = database.filter(query, Certificate, terms)
@ -288,7 +287,7 @@ def create_csr(csr_config):
x509.BasicConstraints(ca=False, path_length=None), critical=True, 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': # if k == 'subAltNames':
# builder = builder.add_extension( # builder = builder.add_extension(
# x509.SubjectAlternativeName([x509.DNSName(n) for n in v]), critical=True, # x509.SubjectAlternativeName([x509.DNSName(n) for n in v]), critical=True,
@ -354,14 +353,16 @@ def create_csr(csr_config):
return csr, pem return csr, pem
# TODO deprecate
def create_challenge(): def create_challenge():
""" """
Create a random and strongish csr challenge. Create a random and strongish csr challenge.
""" """
challenge = ''.join(random.choice(string.ascii_uppercase) 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)) 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.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 return challenge
@ -405,5 +406,3 @@ def stats(**kwargs):
values.append(count) values.append(count)
return {'labels': keys, 'values': values} 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.base import plugins
from lemur.plugins.bases.source import SourcePlugin from lemur.plugins.bases.source import SourcePlugin
def sync(): def sync():
for plugin in plugins: for plugin in plugins:
new = 0 new = 0
@ -42,5 +43,4 @@ def sync():
# TODO associated cert with source # TODO associated cert with source
# TODO update cert if found from different 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() url, err = p1.communicate()
p2 = subprocess.Popen(['openssl', 'ocsp', '-issuer', issuer_chain_path, 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() message, err = p2.communicate()
if 'error' in message or 'Error' in message: 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): 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 Defends against invalid authorities
:param authority_name: :param authority_options:
:return: :raise ValueError: :return: :raise ValueError:
""" """
name = authority_options['name'] name = authority_options['name']
@ -76,7 +76,7 @@ def pem_str(value, name):
""" """
try: try:
x509.load_pem_x509_certificate(str(value), default_backend()) 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)) raise ValueError("The parameter '{0}' needs to be a valid PEM string".format(name))
return value return value
@ -91,12 +91,11 @@ def private_key_str(value, name):
""" """
try: try:
serialization.load_pem_private_key(str(value), None, backend=default_backend()) 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)) raise ValueError("The parameter '{0}' needs to be a valid RSA private key".format(name))
return value return value
class CertificatesList(AuthenticatedResource): class CertificatesList(AuthenticatedResource):
""" Defines the 'certificates' endpoint """ """ Defines the 'certificates' endpoint """
def __init__(self): def __init__(self):
@ -274,8 +273,8 @@ class CertificatesList(AuthenticatedResource):
self.reqparse.add_argument('destinations', type=list, default=[], location='json') self.reqparse.add_argument('destinations', type=list, default=[], location='json')
self.reqparse.add_argument('elbs', type=list, location='json') self.reqparse.add_argument('elbs', type=list, location='json')
self.reqparse.add_argument('owner', type=str, 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('validityStart', type=str, location='json') # TODO validate
self.reqparse.add_argument('validityEnd', type=str, location='json') # parse date 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('authority', type=valid_authority, location='json')
self.reqparse.add_argument('description', type=str, location='json') self.reqparse.add_argument('description', type=str, location='json')
self.reqparse.add_argument('country', 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 = Blueprint('healthCheck', __name__)
@mod.route('/healthcheck') @mod.route('/healthcheck')
def health(): def health():
return 'ok' return 'ok'

View File

@ -8,6 +8,7 @@
""" """
from flask import current_app from flask import current_app
# inspired by https://github.com/getsentry/sentry # inspired by https://github.com/getsentry/sentry
class InstanceManager(object): class InstanceManager(object):
def __init__(self, class_list=None, instances=True): def __init__(self, class_list=None, instances=True):
@ -61,4 +62,4 @@ class InstanceManager(object):
continue continue
self.cache = results self.cache = results
return results return results

View File

@ -6,8 +6,8 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
from flask import current_app
import boto.ses import boto.ses
from flask import current_app
from lemur.templates.config import env from lemur.templates.config import env
@ -22,8 +22,7 @@ def send(subject, data, email_type, recipients):
:param recipients: :param recipients:
""" """
conn = boto.connect_ses() conn = boto.connect_ses()
#jinja template depending on type # jinja template depending on type
template = env.get_template('{}.html'.format(email_type)) template = env.get_template('{}.html'.format(email_type))
body = template.render(**data) body = template.render(**data)
conn.send_email(current_app.config.get("LEMUR_EMAIL"), subject, body, recipients, format='html') 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 import marshal
from flask.ext.restful.reqparse import RequestParser from flask.ext.restful.reqparse import RequestParser
from flask.ext.sqlalchemy import Pagination from flask.ext.sqlalchemy import Pagination

View File

@ -6,5 +6,3 @@
SAN_NAMING_TEMPLATE = "SAN-{subject}-{issuer}-{not_before}-{not_after}" SAN_NAMING_TEMPLATE = "SAN-{subject}-{issuer}-{not_before}-{not_after}"
DEFAULT_NAMING_TEMPLATE = "{subject}-{issuer}-{not_before}-{not_after}" DEFAULT_NAMING_TEMPLATE = "{subject}-{issuer}-{not_before}-{not_after}"
NONSTANDARD_NAMING_TEMPLATE = "{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> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
from flask import current_app
from sqlalchemy import exc from sqlalchemy import exc
from sqlalchemy.sql import and_, or_ from sqlalchemy.sql import and_, or_
from lemur.extensions import db from lemur.extensions import db
from lemur.exceptions import AttrNotFound, IntegrityError, DuplicateError from lemur.exceptions import AttrNotFound, DuplicateError
def filter_none(kwargs): def filter_none(kwargs):
@ -126,7 +124,7 @@ def get(model, value, field="id"):
query = session_query(model) query = session_query(model)
try: try:
return query.filter(getattr(model, field) == value).one() return query.filter(getattr(model, field) == value).one()
except: except Exception:
return return
@ -209,7 +207,7 @@ def sort(query, model, field, direction):
direction = getattr(field, direction) direction = getattr(field, direction)
query = query.order_by(direction()) query = query.order_by(direction())
return query return query
except AttributeError as e: except AttributeError:
raise AttrNotFound(field) raise AttrNotFound(field)
@ -274,6 +272,3 @@ def sort_and_page(query, model, args):
query = sort(query, model, sort_by, sort_dir) query = sort(query, model, sort_by, sort_dir)
return paginate(query, page, count) return paginate(query, page, count)

View File

@ -9,6 +9,7 @@ from flask import make_response, request, current_app
from functools import update_wrapper from functools import update_wrapper
# this is only used for dev
def crossdomain(origin=None, methods=None, headers=None, def crossdomain(origin=None, methods=None, headers=None,
max_age=21600, attach_to_all=True, max_age=21600, attach_to_all=True,
automatic_options=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-Origin'] = origin
h['Access-Control-Allow-Methods'] = get_methods() h['Access-Control-Allow-Methods'] = get_methods()
h['Access-Control-Max-Age'] = str(max_age) 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 "
h['Access-Control-Allow-Headers'] = "Origin, X-Requested-With, Content-Type, Accept, Authorization " # headers
h['Access-Control-Allow-Credentials'] = 'true' h['Access-Control-Allow-Credentials'] = 'true'
return resp return resp
f.provide_automatic_options = False f.provide_automatic_options = False
return update_wrapper(wrapped_function, f) return update_wrapper(wrapped_function, f)
return decorator return decorator

View File

@ -7,18 +7,13 @@ ADMINS = frozenset([''])
THREADS_PER_PAGE = 8 THREADS_PER_PAGE = 8
############# # General
## General ##
#############
# These will need to be set to `True` if you are developing locally # These will need to be set to `True` if you are developing locally
CORS = False CORS = False
debug = False debug = False
############# # Logging
## Logging ##
#############
LOG_LEVEL = "DEBUG" LOG_LEVEL = "DEBUG"
LOG_FILE = "lemur.log" LOG_FILE = "lemur.log"

View File

@ -12,6 +12,7 @@ from lemur.database import db
from lemur.plugins.base import plugins from lemur.plugins.base import plugins
class Destination(db.Model): class Destination(db.Model):
__tablename__ = 'destinations' __tablename__ = 'destinations'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)

View File

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

View File

@ -229,7 +229,6 @@ class Destinations(AuthenticatedResource):
return {'result': True} return {'result': True}
class CertificateDestinations(AuthenticatedResource): class CertificateDestinations(AuthenticatedResource):
""" Defines the 'certificate/<int:certificate_id/destinations'' endpoint """ """ Defines the 'certificate/<int:certificate_id/destinations'' endpoint """
def __init__(self): def __init__(self):
@ -274,5 +273,5 @@ class CertificateDestinations(AuthenticatedResource):
api.add_resource(DestinationsList, '/destinations', endpoint='destinations') api.add_resource(DestinationsList, '/destinations', endpoint='destinations')
api.add_resource(Destinations, '/destinations/<int:destination_id>', endpoint='account') 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 = self.as_dict()
blob['certificates'] = [x.id for x in self.certificate] blob['certificates'] = [x.id for x in self.certificate]
return blob return blob

View File

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

View File

@ -6,7 +6,7 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. 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 sqlalchemy.orm import relationship
from lemur.database import db from lemur.database import db
@ -16,7 +16,7 @@ from lemur.listeners.models import Listener
class ELB(db.Model): class ELB(db.Model):
__tablename__ = 'elbs' __tablename__ = 'elbs'
id = Column(BigInteger, primary_key=True) 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)) region = Column(String(32))
name = Column(String(128)) name = Column(String(128))
vpc_id = 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.elbs.models import ELB
from lemur.listeners.models import Listener from lemur.listeners.models import Listener
def get_all(account_id, elb_name): def get_all(account_id, elb_name):
""" """
Retrieves all ELBs in a given account Retrieves all ELBs in a given account
@ -112,7 +113,7 @@ def stats(**kwargs):
if kwargs.get('active') == 'true': if kwargs.get('active') == 'true':
query = query.join(ELB.listeners) 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() items = query.group_by(attr).all()
@ -121,5 +122,3 @@ def stats(**kwargs):
if key: if key:
results.append({"key": key, "y": count}) results.append({"key": key, "y": count})
return results 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 :copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details. :license: Apache, see LICENSE for more details.
""" """
from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy() db = SQLAlchemy()
@ -15,4 +14,3 @@ bcrypt = Bcrypt()
from flask.ext.principal import Principal from flask.ext.principal import Principal
principal = Principal() principal = Principal()

View File

@ -19,7 +19,6 @@ from logging.handlers import RotatingFileHandler
from flask import Flask from flask import Flask
from lemur.common.health import mod as health from lemur.common.health import mod as health
from lemur.exceptions import NoEncryptionKeyFound
from lemur.extensions import db, migrate, principal from lemur.extensions import db, migrate, principal
@ -161,7 +160,6 @@ def install_plugins(app):
try: try:
plugin = ep.load() plugin = ep.load()
except Exception: except Exception:
import sys
import traceback import traceback
app.logger.error("Failed to load plugin %r:\n%s\n" % (ep.name, traceback.format_exc())) app.logger.error("Failed to load plugin %r:\n%s\n" % (ep.name, traceback.format_exc()))
else: else:

View File

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

View File

@ -18,7 +18,7 @@ from lemur.listeners.models import Listener
from lemur.elbs import service as elb_service from lemur.elbs import service as elb_service
from lemur.certificates import service as certificate_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): 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) cert = verify_attachment(certificate_id, account_number)
listener_tuple = (load_balancer_port, instance_port, load_balancer_protocol, cert.get_art(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'} return {'message': 'Listener has been created'}
@ -98,7 +98,7 @@ def update(listener_id, **kwargs):
database.update(listener) database.update(listener)
listener_tuple = (listener.load_balancer_port, listener.instance_port, listener.load_balancer_protocol, arn,) 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'} return {'message': 'Listener has been updated'}
@ -106,7 +106,7 @@ def update(listener_id, **kwargs):
def delete(listener_id): def delete(listener_id):
# first try to delete the listener in aws # first try to delete the listener in aws
listener = get(listener_id) 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 # cleanup operation in lemur
database.delete(listener) database.delete(listener)
@ -149,7 +149,7 @@ def stats(**kwargs):
query = query.filter(ELB.account_id == kwargs.get('account_id')) query = query.filter(ELB.account_id == kwargs.get('account_id'))
if kwargs.get('active') == 'true': 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() items = query.group_by(attr).all()
results = [] results = []
@ -157,6 +157,3 @@ def stats(**kwargs):
if key: if key:
results.append({"key": key, "y": count}) results.append({"key": key, "y": count})
return results return results

View File

@ -20,19 +20,18 @@ from lemur.plugins.base import plugins
from lemur.certificates.verify import verify_string from lemur.certificates.verify import verify_string
from lemur.certificates import sync from lemur.certificates import sync
from lemur.elbs.sync import sync_all_elbs
from lemur import create_app from lemur import create_app
# Needed to be imported so that SQLAlchemy create_all can find our models # Needed to be imported so that SQLAlchemy create_all can find our models
from lemur.users.models import User from lemur.users.models import User # noqa
from lemur.roles.models import Role from lemur.roles.models import Role # noqa
from lemur.authorities.models import Authority from lemur.authorities.models import Authority # noqa
from lemur.certificates.models import Certificate from lemur.certificates.models import Certificate # noqa
from lemur.destinations.models import Destination from lemur.destinations.models import Destination # noqa
from lemur.domains.models import Domain from lemur.domains.models import Domain # noqa
from lemur.elbs.models import ELB from lemur.elbs.models import ELB # noqa
from lemur.listeners.models import Listener from lemur.listeners.models import Listener # noqa
manager = Manager(create_app) manager = Manager(create_app)
manager.add_option('-c', '--config', dest='config') manager.add_option('-c', '--config', dest='config')
@ -135,6 +134,7 @@ SQLALCHEMY_DATABASE_URI = ''
#VERSIGN_EMAIL = '' #VERSIGN_EMAIL = ''
""" """
@MigrateCommand.command @MigrateCommand.command
def create(): def create():
database.db.create_all() database.db.create_all()
@ -214,7 +214,7 @@ class Sync(Command):
sys.stdout.write("[!] Starting to sync with AWS!\n") sys.stdout.write("[!] Starting to sync with AWS!\n")
try: try:
sync.aws() sync.aws()
#sync_all_elbs() # sync_all_elbs()
sys.stdout.write("[+] Finished syncing with AWS!\n") sys.stdout.write("[+] Finished syncing with AWS!\n")
except Exception as e: except Exception as e:
sys.stdout.write("[-] Syncing with AWS failed!\n") 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 from lemur.database import db
certificate_associations = db.Table('certificate_associations', certificate_associations = db.Table('certificate_associations',
Column('domain_id', Integer, ForeignKey('domains.id')), Column('domain_id', Integer, ForeignKey('domains.id')),
Column('certificate_id', Integer, ForeignKey('certificates.id')) Column('certificate_id', Integer, ForeignKey('certificates.id'))
) )
certificate_destination_associations = db.Table('certificate_destination_associations', certificate_destination_associations = db.Table('certificate_destination_associations',
Column('destination_id', Integer, ForeignKey('destinations.id', ondelete='cascade')), Column('destination_id', Integer,
Column('certificate_id', Integer, ForeignKey('certificates.id', ondelete='cascade')) ForeignKey('destinations.id', ondelete='cascade')),
) Column('certificate_id', Integer,
ForeignKey('certificates.id', ondelete='cascade'))
)
roles_users = db.Table('roles_users', roles_users = db.Table('roles_users',
Column('user_id', Integer, ForeignKey('users.id')), Column('user_id', Integer, ForeignKey('users.id')),
Column('role_id', Integer, ForeignKey('roles.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)) 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.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')) query = query.filter(Certificate.not_after >= arrow.utcnow().format('YYYY-MM-DD'))
ss_list.extend(query.all()) ss_list.extend(query.all())

View File

@ -1,4 +1,4 @@
from __future__ import absolute_import from __future__ import absolute_import
from lemur.plugins.base import * # NOQA from lemur.plugins.base import * # noqa
from lemur.plugins.bases import * # NOQA from lemur.plugins.bases import * # noqa

View File

@ -9,7 +9,7 @@
from __future__ import absolute_import, print_function from __future__ import absolute_import, print_function
from lemur.plugins.base.manager import PluginManager from lemur.plugins.base.manager import PluginManager
from lemur.plugins.base.v1 import * # NOQA from lemur.plugins.base.v1 import * # noqa
plugins = PluginManager() plugins = PluginManager()
register = plugins.register register = plugins.register

View File

@ -8,6 +8,7 @@
from flask import current_app from flask import current_app
from lemur.common.managers import InstanceManager from lemur.common.managers import InstanceManager
# inspired by https://github.com/getsentry/sentry # inspired by https://github.com/getsentry/sentry
class PluginManager(InstanceManager): class PluginManager(InstanceManager):
def __iter__(self): def __iter__(self):
@ -57,4 +58,3 @@ class PluginManager(InstanceManager):
def unregister(self, cls): def unregister(self, cls):
self.remove('%s.%s' % (cls.__module__, cls.__name__)) self.remove('%s.%s' % (cls.__module__, cls.__name__))
return cls return cls

View File

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

View File

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

View File

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

View File

@ -8,6 +8,7 @@
""" """
from lemur.plugins.base import Plugin from lemur.plugins.base import Plugin
class IssuerPlugin(Plugin): class IssuerPlugin(Plugin):
""" """
This is the base class from which all of the supported This is the base class from which all of the supported
@ -20,4 +21,3 @@ class IssuerPlugin(Plugin):
def create_authority(self): def create_authority(self):
raise NotImplemented raise NotImplemented

View File

@ -8,6 +8,7 @@
""" """
from lemur.plugins.base import Plugin from lemur.plugins.base import Plugin
class SourcePlugin(Plugin): class SourcePlugin(Plugin):
type = 'source' type = 'source'
@ -16,4 +17,3 @@ class SourcePlugin(Plugin):
def get_options(self): def get_options(self):
return {} return {}

View File

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

View File

@ -38,6 +38,7 @@ def is_valid(listener_tuple):
return listener_tuple return listener_tuple
def get_all_regions(): def get_all_regions():
""" """
Retrieves all current EC2 regions. Retrieves all current EC2 regions.
@ -49,6 +50,7 @@ def get_all_regions():
regions.append(r.name) regions.append(r.name)
return regions return regions
def get_all_elbs(account_number, region): def get_all_elbs(account_number, region):
""" """
Fetches all elb objects for a given account and region. Fetches all elb objects for a given account and region.
@ -74,7 +76,6 @@ def get_all_elbs(account_number, region):
# return elbs # return elbs
def attach_certificate(account_number, region, name, port, certificate_id): def attach_certificate(account_number, region, name, port, certificate_id):
""" """
Attaches a certificate to a listener, throws exception Attaches a certificate to a listener, throws exception
@ -137,4 +138,3 @@ def delete_listeners(account_number, region, name, ports):
:return: :return:
""" """
return assume_service(account_number, 'elb', region).delete_load_balancer_listeners(name, ports) 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: :param cert_chain:
:return: :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): def delete_cert(account_number, cert):
@ -109,5 +110,3 @@ def digest_aws_cert_response(response):
chain = cert['certificate_chain'] chain = cert['certificate_chain']
return str(body), str(chain), return str(body), str(chain),

View File

@ -35,11 +35,11 @@ class AWSDestinationPlugin(DestinationPlugin):
'helpMessage': 'Must be a valid AWS account number!', 'helpMessage': 'Must be a valid AWS account number!',
} }
] ]
#'elb': { # 'elb': {
# 'name': {'type': 'name'}, # 'name': {'type': 'name'},
# 'region': {'type': 'str'}, # 'region': {'type': 'str'},
# 'port': {'type': 'int'} # 'port': {'type': 'int'}
#} # }
def upload(self, cert, private_key, cert_chain, options, **kwargs): def upload(self, cert, private_key, cert_chain, options, **kwargs):
iam.upload_cert(find_value('accountNumber', options), cert, private_key, cert_chain=cert_chain) 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': elif service in 'elb':
return boto.ec2.elb.connect_to_region( return boto.ec2.elb.connect_to_region(
region, region,
aws_access_key_id=role.credentials.access_key, aws_access_key_id=role.credentials.access_key,
aws_secret_access_key=role.credentials.secret_key, aws_secret_access_key=role.credentials.secret_key,
security_token=role.credentials.session_token) security_token=role.credentials.session_token)
elif service in 'vpc': elif service in 'vpc':
return boto.connect_vpc( return boto.connect_vpc(
aws_access_key_id=role.credentials.access_key, aws_access_key_id=role.credentials.access_key,
aws_secret_access_key=role.credentials.secret_key, aws_secret_access_key=role.credentials.secret_key,
security_token=role.credentials.session_token) security_token=role.credentials.session_token)

View File

@ -2,4 +2,4 @@ try:
VERSION = __import__('pkg_resources') \ VERSION = __import__('pkg_resources') \
.get_distribution(__name__).version .get_distribution(__name__).version
except Exception, e: 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 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): class CloudCAException(LemurException):
@ -72,7 +72,8 @@ def get_default_issuance(options):
if not options.get('validityStart') and not options.get('validityEnd'): if not options.get('validityStart') and not options.get('validityEnd'):
start = arrow.utcnow() start = arrow.utcnow()
options['validityStart'] = start.floor('second').isoformat() 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 return options
@ -95,7 +96,8 @@ def convert_date_to_utc_time(date):
:return: :return:
""" """
d = arrow.get(date) 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): def process_response(response):
@ -152,7 +154,9 @@ class CloudCA(object):
self.session.cert = current_app.config.get('CLOUDCA_PEM_PATH') self.session.cert = current_app.config.get('CLOUDCA_PEM_PATH')
self.ca_bundle = current_app.config.get('CLOUDCA_BUNDLE') self.ca_bundle = current_app.config.get('CLOUDCA_BUNDLE')
else: 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) super(CloudCA, self).__init__(*args, **kwargs)
@ -203,7 +207,7 @@ class CloudCA(object):
for ca in self.get(endpoint)['data']['caList']: for ca in self.get(endpoint)['data']['caList']:
try: try:
authorities.append(ca['caName']) authorities.append(ca['caName'])
except AttributeError as e: except AttributeError:
current_app.logger.error("No authority has been defined for {}".format(ca['caName'])) current_app.logger.error("No authority has been defined for {}".format(ca['caName']))
return authorities return authorities
@ -235,7 +239,8 @@ class CloudCAIssuerPlugin(IssuerPlugin, CloudCA):
options['validityStart'] = convert_date_to_utc_time(options['validityStart']).isoformat() options['validityStart'] = convert_date_to_utc_time(options['validityStart']).isoformat()
options['validityEnd'] = convert_date_to_utc_time(options['validityEnd']).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) json = process_response(response)
roles = [] roles = []
@ -326,7 +331,8 @@ class CloudCASourcePlugin(SourcePlugin, CloudCA):
:return: :return:
""" """
endpoint = '{0}/getCert'.format(API_ENDPOINT) 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) raw = process_response(response)
certs = [] certs = []

View File

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

View File

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

View File

@ -151,4 +151,3 @@ class VerisignIssuerPlugin(IssuerPlugin):
url = current_app.config.get("VERISIGN_URL") + '/getTokens' url = current_app.config.get("VERISIGN_URL") + '/getTokens'
response = self.session.post(url, headers={'content-type': 'application/x-www-form-urlencoded'}) response = self.session.post(url, headers={'content-type': 'application/x-www-form-urlencoded'})
return handle_response(response.content)['Response']['Order'] 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(PluginsList, '/plugins', endpoint='plugins')
api.add_resource(PluginsTypeList, '/plugins/<plugin_type>', endpoint='pluginType') api.add_resource(PluginsTypeList, '/plugins/<plugin_type>', endpoint='pluginType')

View File

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

View File

@ -15,6 +15,7 @@ from lemur import database
from lemur.roles.models import Role from lemur.roles.models import Role
from lemur.users.models import User from lemur.users.models import User
def update(role_id, name, description, users): def update(role_id, name, description, users):
""" """
Update a role Update a role
@ -122,4 +123,3 @@ def render(args):
query = database.sort(query, Role, sort_by, sort_dir) query = database.sort(query, Role, sort_by, sort_dir)
return database.paginate(query, page, count) return database.paginate(query, page, count)

View File

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

View File

@ -35,7 +35,7 @@ angular.module('lemur')
$scope.getAuthorityStatus = function () { $scope.getAuthorityStatus = function () {
var def = $q.defer(); 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; return def;
}; };

View File

@ -48,7 +48,7 @@ angular.module('lemur')
$scope.getCertificateStatus = function () { $scope.getCertificateStatus = function () {
var def = $q.defer(); 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; return def;
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
from lemur.destinations.service import * from lemur.destinations.service import * # noqa
from lemur.destinations.views import * from lemur.destinations.views import * # noqa
from json import dumps from json import dumps
@ -40,6 +40,7 @@ def test_destination_patch(client):
VALID_USER_HEADER_TOKEN = { VALID_USER_HEADER_TOKEN = {
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'} 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'}
def test_auth_destination_get(client): def test_auth_destination_get(client):
assert client.get(api.url_for(Destinations, destination_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200 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 = { VALID_ADMIN_HEADER_TOKEN = {
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'} 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'}
def test_admin_destination_get(client): def test_admin_destination_get(client):
assert client.get(api.url_for(Destinations, destination_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 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): def test_admin_destinations_crud(client):
assert client.post(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400 assert client.post(api.url_for(DestinationsList), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400
data = {'destinationNumber': 111, 'label': 'test', 'comments': 'test'} 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 resp.status_code == 200
assert client.get(api.url_for(Destinations, destination_id=resp.json['id']), headers=VALID_ADMIN_HEADER_TOKEN).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) 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 * # noqa
from lemur.authorities.views import *
#def test_crud(session): # def test_crud(session):
# role = create('role1') # role = create('role1')
# assert role.id > 0 # assert role.id > 0
# #

View File

@ -1,5 +1,6 @@
import pytest import pytest
from lemur.certificates.views import * from lemur.certificates.views import * # noqa
def test_valid_authority(session): def test_valid_authority(session):
assert 1 == 2 assert 1 == 2
@ -87,6 +88,7 @@ def test_cert_get_bitstrength():
from lemur.certificates.models import cert_get_bitstrength from lemur.certificates.models import cert_get_bitstrength
assert cert_get_bitstrength(INTERNAL_VALID_LONG_CERT) == 2048 assert cert_get_bitstrength(INTERNAL_VALID_LONG_CERT) == 2048
def test_cert_get_issuer(): def test_cert_get_issuer():
from lemur.tests.certs import INTERNAL_VALID_LONG_CERT from lemur.tests.certs import INTERNAL_VALID_LONG_CERT
from lemur.certificates.models import cert_get_issuer 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): 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 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): def test_domain_get(client):
assert client.get(api.url_for(Domains, domain_id=1)).status_code == 401 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 = { VALID_USER_HEADER_TOKEN = {
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'} 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'}
def test_auth_domain_get(client): def test_auth_domain_get(client):
assert client.get(api.url_for(Domains, domain_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200 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 = { VALID_ADMIN_HEADER_TOKEN = {
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'} 'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'}
def test_admin_domain_get(client): def test_admin_domain_get(client):
assert client.get(api.url_for(Domains, domain_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200 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): 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 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): 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 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 # import boto
from lemur.tests import LemurTestCase # 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_sts
# @mock_elb # @mock_elb
# def test_add_listener(self): # 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_sts
# @mock_iam # @mock_iam
# def test_get_all_server_certs(self): # 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): # def test_validate_authority(self):
# pass # pass
# #

View File

@ -1,6 +1,6 @@
from json import dumps from json import dumps
from lemur.roles.service import * from lemur.roles.service import * # noqa
from lemur.roles.views import * from lemur.roles.views import * # noqa
def test_crud(session): def test_crud(session):

View File

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

View File

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