Skip to content

Commit

Permalink
Closes #284 (#336)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevgliss authored Jun 27, 2016
1 parent b44a7c7 commit fe9703d
Show file tree
Hide file tree
Showing 36 changed files with 1,134 additions and 181 deletions.
2 changes: 1 addition & 1 deletion gulp/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ gulp.task('dev:styles', function () {
'bower_components/angular-loading-bar/src/loading-bar.css',
'bower_components/angular-ui-switch/angular-ui-switch.css',
'bower_components/angular-wizard/dist/angular-wizard.css',
'bower_components/ng-table/ng-table.css',
'bower_components/ng-table/dist/ng-table.css',
'bower_components/angularjs-toaster/toaster.css',
'bower_components/angular-ui-select/dist/select.css',
'lemur/static/app/styles/lemur.css'
Expand Down
4 changes: 3 additions & 1 deletion lemur/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from lemur.plugins.views import mod as plugins_bp
from lemur.notifications.views import mod as notifications_bp
from lemur.sources.views import mod as sources_bp
from lemur.endpoints.views import mod as endpoints_bp

from lemur.__about__ import (
__author__, __copyright__, __email__, __license__, __summary__, __title__,
Expand All @@ -47,7 +48,8 @@
defaults_bp,
plugins_bp,
notifications_bp,
sources_bp
sources_bp,
endpoints_bp
)


Expand Down
10 changes: 0 additions & 10 deletions lemur/authorities/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,6 @@ def create(**kwargs):
else:
kwargs['roles'] = roles

if kwargs['type'] == 'subca':
description = "This is the ROOT certificate for the {0} sub certificate authority the parent \
authority is {1}.".format(kwargs.get('name'), kwargs.get('parent'))
else:
description = "This is the ROOT certificate for the {0} certificate authority.".format(
kwargs.get('name')
)

kwargs['description'] = description

cert = upload(**kwargs)
kwargs['authority_certificate'] = cert

Expand Down
41 changes: 28 additions & 13 deletions lemur/certificates/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@

from flask import current_app

from sqlalchemy import event, Integer, ForeignKey, String, DateTime, PassiveDefault, func, Column, Text, Boolean
from sqlalchemy.orm import relationship
from sqlalchemy.sql.expression import case
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import event, Integer, ForeignKey, String, DateTime, PassiveDefault, func, Column, Text, Boolean

from lemur.database import db
from lemur.models import certificate_associations, certificate_source_associations, \
Expand Down Expand Up @@ -73,6 +75,8 @@ class Certificate(db.Model):
secondaryjoin=id == certificate_replacement_associations.c.replaced_certificate_id, # noqa
backref='replaced')

endpoints = relationship("Endpoint", backref='certificate')

def __init__(self, **kwargs):
cert = defaults.parse_certificate(kwargs['body'])

Expand Down Expand Up @@ -104,22 +108,33 @@ def __init__(self, **kwargs):
for domain in defaults.domains(cert):
self.domains.append(Domain(name=domain))

@property
def is_expired(self):
if self.not_after < datetime.datetime.now():
@hybrid_property
def expired(self):
if self.not_after <= datetime.datetime.now():
return True

@property
def is_unused(self):
if self.elb_listeners.count() == 0:
@expired.expression
def expired(cls):
return case(
[
(cls.now_after <= datetime.datetime.now(), True)
],
else_=False
)

@hybrid_property
def revoked(self):
if 'revoked' == self.status:
return True

@property
def is_revoked(self):
# we might not yet know the condition of the cert
if self.status:
if 'revoked' in self.status:
return True
@revoked.expression
def revoked(cls):
return case(
[
(cls.status == 'revoked', True)
],
else_=False
)

def get_arn(self, account_number):
"""
Expand Down
4 changes: 2 additions & 2 deletions lemur/certificates/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from marshmallow.exceptions import ValidationError

from lemur.schemas import AssociatedAuthoritySchema, AssociatedDestinationSchema, AssociatedCertificateSchema, \
AssociatedNotificationSchema, PluginInputSchema, ExtensionSchema, AssociatedRoleSchema
AssociatedNotificationSchema, PluginInputSchema, ExtensionSchema, AssociatedRoleSchema, EndpointNestedOutputSchema

from lemur.authorities.schemas import AuthorityNestedOutputSchema
from lemur.destinations.schemas import DestinationNestedOutputSchema
Expand Down Expand Up @@ -120,7 +120,7 @@ class CertificateOutputSchema(LemurOutputSchema):
replaces = fields.Nested(CertificateNestedOutputSchema, many=True)
authority = fields.Nested(AuthorityNestedOutputSchema)
roles = fields.Nested(RoleNestedOutputSchema, many=True)
endpoints = fields.List(fields.Dict(), missing=[])
endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[])


class CertificateUploadInputSchema(CertificateSchema):
Expand Down
11 changes: 8 additions & 3 deletions lemur/certificates/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ def upload(**kwargs):
"""
Allows for pre-made certificates to be imported into Lemur.
"""
from lemur.users import service as user_service
roles = create_certificate_roles(**kwargs)

if kwargs.get('roles'):
Expand All @@ -187,10 +188,14 @@ def upload(**kwargs):
cert = Certificate(**kwargs)

cert = database.create(cert)
g.user.certificates.append(cert)

database.update(cert)
return cert
try:
g.user.certificates.append(cert)
except AttributeError:
user = user_service.get_by_email('lemur@nobody')
user.certificates.append(cert)

return database.update(cert)


def create(**kwargs):
Expand Down
5 changes: 4 additions & 1 deletion lemur/common/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ def bitstrength(cert):
:param cert:
:return: Integer
"""
return cert.public_key().key_size
try:
return cert.public_key().key_size
except AttributeError:
current_app.logger.debug('Unable to get bitstrength.')


def issuer(cert):
Expand Down
Empty file added lemur/endpoints/__init__.py
Empty file.
80 changes: 80 additions & 0 deletions lemur/endpoints/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
.. module: lemur.endpoints.models
:platform: unix
:synopsis: This module contains all of the models need to create a authority within Lemur.
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <[email protected]>
"""
from sqlalchemy.orm import relationship
from sqlalchemy import Column, Integer, String, func, DateTime, PassiveDefault, Boolean, ForeignKey
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.sql.expression import case

from lemur.database import db

from lemur.models import policies_ciphers


BAD_CIPHERS = [
'Protocol-SSLv3',
'Protocol-SSLv2',
'Protocol-TLSv1'
]


class Cipher(db.Model):
__tablename__ = 'ciphers'
id = Column(Integer, primary_key=True)
name = Column(String(128), nullable=False)

@hybrid_property
def deprecated(self):
return self.name in BAD_CIPHERS

@deprecated.expression
def deprecated(cls):
return case(
[
(cls.name in BAD_CIPHERS, True)
],
else_=False
)


class Policy(db.Model):
___tablename__ = 'policies'
id = Column(Integer, primary_key=True)
name = Column(String(128), nullable=True)
ciphers = relationship('Cipher', secondary=policies_ciphers, backref='policy')


class Endpoint(db.Model):
__tablename__ = 'endpoints'
id = Column(Integer, primary_key=True)
owner = Column(String(128))
name = Column(String(128))
dnsname = Column(String(256))
type = Column(String(128))
active = Column(Boolean, default=True)
port = Column(Integer)
date_created = Column(DateTime, PassiveDefault(func.now()), nullable=False)
policy_id = Column(Integer, ForeignKey('policy.id'))
policy = relationship('Policy', backref='endpoint')
certificate_id = Column(Integer, ForeignKey('certificates.id'))

@property
def issues(self):
issues = []

for cipher in self.policy.ciphers:
if cipher.deprecated:
issues.append({'name': 'deprecated cipher', 'value': '{0} has been deprecated consider removing it.'.format(cipher.name)})

if self.certificate.expired:
issues.append({'name': 'expired certificate', 'value': 'There is an expired certificate attached to this endpoint consider replacing it.'})

if self.certificate.revoked:
issues.append({'name': 'revoked', 'value': 'There is a revoked certificate attached to this endpoint consider replacing it.'})

return issues
43 changes: 43 additions & 0 deletions lemur/endpoints/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
.. module: lemur.endpoints.schemas
:platform: unix
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <[email protected]>
"""
from marshmallow import fields

from lemur.common.schema import LemurOutputSchema
from lemur.certificates.schemas import CertificateNestedOutputSchema


class CipherNestedOutputSchema(LemurOutputSchema):
__envelope__ = False
id = fields.Integer()
deprecated = fields.Boolean()
name = fields.String()


class PolicyNestedOutputSchema(LemurOutputSchema):
__envelope__ = False
id = fields.Integer()
name = fields.String()
ciphers = fields.Nested(CipherNestedOutputSchema, many=True)


class EndpointOutputSchema(LemurOutputSchema):
id = fields.Integer()
description = fields.String()
name = fields.String()
dnsname = fields.String()
owner = fields.Email()
type = fields.String()
port = fields.Integer()
active = fields.Boolean()
certificate = fields.Nested(CertificateNestedOutputSchema)
policy = fields.Nested(PolicyNestedOutputSchema)

issues = fields.List(fields.Dict())

endpoint_output_schema = EndpointOutputSchema()
endpoints_output_schema = EndpointOutputSchema(many=True)
Loading

0 comments on commit fe9703d

Please sign in to comment.