* Closes #147 * Fixing tests * Ensuring we can validate max dates.
This commit is contained in:
@ -6,49 +6,35 @@
|
||||
:license: Apache, see LICENSE for more details.
|
||||
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
||||
"""
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy import Column, Integer, String, Text, func, ForeignKey, DateTime, PassiveDefault, Boolean
|
||||
from sqlalchemy.dialects.postgresql import JSON
|
||||
|
||||
from lemur.database import db
|
||||
from lemur.models import roles_authorities
|
||||
from lemur.common import defaults
|
||||
|
||||
|
||||
class Authority(db.Model):
|
||||
__tablename__ = 'authorities'
|
||||
id = Column(Integer, primary_key=True)
|
||||
owner = Column(String(128))
|
||||
owner = Column(String(128), nullable=False)
|
||||
name = Column(String(128), unique=True)
|
||||
body = Column(Text())
|
||||
chain = Column(Text())
|
||||
bits = Column(Integer())
|
||||
cn = Column(String(128))
|
||||
not_before = Column(DateTime)
|
||||
not_after = Column(DateTime)
|
||||
active = Column(Boolean, default=True)
|
||||
date_created = Column(DateTime, PassiveDefault(func.now()), nullable=False)
|
||||
plugin_name = Column(String(64))
|
||||
description = Column(Text)
|
||||
options = Column(JSON)
|
||||
date_created = Column(DateTime, PassiveDefault(func.now()), nullable=False)
|
||||
roles = relationship('Role', secondary=roles_authorities, passive_deletes=True, backref=db.backref('authority'), lazy='dynamic')
|
||||
user_id = Column(Integer, ForeignKey('users.id'))
|
||||
certificates = relationship("Certificate", backref='authority')
|
||||
authority_certificate = relationship("Certificate", backref='root_authority', uselist=False, foreign_keys='Certificate.root_authority_id')
|
||||
certificates = relationship("Certificate", backref='authority', foreign_keys='Certificate.authority_id')
|
||||
|
||||
def __init__(self, name, owner, plugin_name, body, roles=None, chain=None, description=None):
|
||||
cert = x509.load_pem_x509_certificate(bytes(body), default_backend())
|
||||
self.name = name
|
||||
self.body = body
|
||||
self.chain = chain
|
||||
self.owner = owner
|
||||
self.description = description
|
||||
self.plugin_name = plugin_name
|
||||
self.cn = defaults.common_name(cert)
|
||||
self.not_before = defaults.not_before(cert)
|
||||
self.not_after = defaults.not_after(cert)
|
||||
|
||||
if roles:
|
||||
self.roles = roles
|
||||
def __init__(self, **kwargs):
|
||||
self.owner = kwargs['owner']
|
||||
self.roles = kwargs.get('roles', [])
|
||||
self.name = kwargs.get('name')
|
||||
self.description = kwargs.get('description')
|
||||
self.authority_certificate = kwargs['authority_certificate']
|
||||
self.plugin_name = kwargs['plugin']['slug']
|
||||
|
@ -12,6 +12,7 @@ from marshmallow import validate
|
||||
from marshmallow.exceptions import ValidationError
|
||||
|
||||
from lemur.schemas import PluginInputSchema, PluginOutputSchema, ExtensionSchema, AssociatedAuthoritySchema, AssociatedRoleSchema
|
||||
from lemur.users.schemas import UserNestedOutputSchema
|
||||
from lemur.common.schema import LemurInputSchema, LemurOutputSchema
|
||||
from lemur.common import validators
|
||||
|
||||
@ -61,25 +62,39 @@ class AuthorityInputSchema(LemurInputSchema):
|
||||
|
||||
|
||||
class AuthorityUpdateSchema(LemurInputSchema):
|
||||
owner = fields.Email()
|
||||
owner = fields.Email(required=True)
|
||||
description = fields.String()
|
||||
active = fields.Boolean()
|
||||
roles = fields.Nested(AssociatedRoleSchema(many=True))
|
||||
|
||||
|
||||
class RootAuthorityCertificateOutputSchema(LemurOutputSchema):
|
||||
__envelope__ = False
|
||||
id = fields.Integer()
|
||||
active = fields.Boolean()
|
||||
bits = fields.Integer()
|
||||
body = fields.String()
|
||||
chain = fields.String()
|
||||
description = fields.String()
|
||||
name = fields.String()
|
||||
cn = fields.String()
|
||||
not_after = fields.DateTime()
|
||||
not_before = fields.DateTime()
|
||||
owner = fields.Email()
|
||||
status = fields.Boolean()
|
||||
user = fields.Nested(UserNestedOutputSchema)
|
||||
|
||||
|
||||
class AuthorityOutputSchema(LemurOutputSchema):
|
||||
id = fields.Integer()
|
||||
description = fields.String()
|
||||
name = fields.String()
|
||||
owner = fields.Email()
|
||||
not_before = fields.DateTime()
|
||||
not_after = fields.DateTime()
|
||||
plugin = fields.Nested(PluginOutputSchema)
|
||||
body = fields.String()
|
||||
chain = fields.String()
|
||||
active = fields.Boolean()
|
||||
options = fields.Dict()
|
||||
roles = fields.List(fields.Nested(AssociatedRoleSchema))
|
||||
authority_certificate = fields.Nested(RootAuthorityCertificateOutputSchema)
|
||||
|
||||
|
||||
class AuthorityNestedOutputSchema(LemurOutputSchema):
|
||||
@ -87,13 +102,8 @@ class AuthorityNestedOutputSchema(LemurOutputSchema):
|
||||
description = fields.String()
|
||||
name = fields.String()
|
||||
owner = fields.Email()
|
||||
not_before = fields.DateTime()
|
||||
not_after = fields.DateTime()
|
||||
plugin = fields.Nested(PluginOutputSchema)
|
||||
body = fields.String()
|
||||
chain = fields.String()
|
||||
active = fields.Boolean()
|
||||
options = fields.Dict()
|
||||
|
||||
|
||||
authority_update_schema = AuthorityUpdateSchema()
|
||||
|
@ -9,14 +9,13 @@
|
||||
|
||||
"""
|
||||
from flask import g
|
||||
from flask import current_app
|
||||
|
||||
from lemur import database
|
||||
from lemur.extensions import metrics
|
||||
from lemur.authorities.models import Authority
|
||||
from lemur.roles import service as role_service
|
||||
from lemur.notifications import service as notification_service
|
||||
|
||||
from lemur.certificates.models import Certificate
|
||||
from lemur.certificates.service import upload
|
||||
|
||||
|
||||
def update(authority_id, description=None, owner=None, active=None, roles=None):
|
||||
@ -40,42 +39,28 @@ def update(authority_id, description=None, owner=None, active=None, roles=None):
|
||||
return database.update(authority)
|
||||
|
||||
|
||||
def create(kwargs):
|
||||
def mint(**kwargs):
|
||||
"""
|
||||
Create a new authority.
|
||||
Creates the authority based on the plugin provided.
|
||||
"""
|
||||
issuer = kwargs['plugin']['plugin_object']
|
||||
body, chain, roles = issuer.create_authority(kwargs)
|
||||
return body, chain, roles
|
||||
|
||||
|
||||
def create_authority_roles(roles, **kwargs):
|
||||
"""
|
||||
Creates all of the necessary authority roles.
|
||||
:param roles:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
|
||||
issuer = kwargs['plugin']['plugin_object']
|
||||
|
||||
kwargs['creator'] = g.current_user.email
|
||||
cert_body, intermediate, issuer_roles = issuer.create_authority(kwargs)
|
||||
|
||||
cert = Certificate(body=cert_body, chain=intermediate, **kwargs)
|
||||
|
||||
if kwargs['type'] == 'subca':
|
||||
cert.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:
|
||||
cert.description = "This is the ROOT certificate for the {0} certificate authority.".format(
|
||||
kwargs.get('name')
|
||||
)
|
||||
|
||||
cert.user = g.current_user
|
||||
|
||||
cert.notifications = notification_service.create_default_expiration_notifications(
|
||||
'DEFAULT_SECURITY',
|
||||
current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')
|
||||
)
|
||||
|
||||
# we create and attach any roles that the issuer gives us
|
||||
role_objs = []
|
||||
for r in issuer_roles:
|
||||
for r in roles:
|
||||
role = role_service.create(
|
||||
r['name'],
|
||||
password=r['password'],
|
||||
description="{0} auto generated role".format(issuer.title),
|
||||
description="Auto generated role for {0}".format(kwargs['plugin']['plugin_object'].title),
|
||||
username=r['username'])
|
||||
|
||||
# the user creating the authority should be able to administer it
|
||||
@ -93,22 +78,39 @@ def create(kwargs):
|
||||
)
|
||||
|
||||
role_objs.append(owner_role)
|
||||
return role_objs
|
||||
|
||||
authority = Authority(
|
||||
kwargs.get('name'),
|
||||
kwargs['owner'],
|
||||
issuer.slug,
|
||||
cert_body,
|
||||
description=kwargs['description'],
|
||||
chain=intermediate,
|
||||
roles=role_objs
|
||||
)
|
||||
|
||||
database.update(cert)
|
||||
def create(**kwargs):
|
||||
"""
|
||||
Creates a new authority.
|
||||
"""
|
||||
kwargs['creator'] = g.user.email
|
||||
body, chain, roles = mint(**kwargs)
|
||||
|
||||
kwargs['body'] = body
|
||||
kwargs['chain'] = chain
|
||||
|
||||
kwargs['roles'] = create_authority_roles(roles, **kwargs)
|
||||
|
||||
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
|
||||
|
||||
authority = Authority(**kwargs)
|
||||
authority = database.create(authority)
|
||||
g.user.authorities.append(authority)
|
||||
|
||||
g.current_user.authorities.append(authority)
|
||||
|
||||
metrics.send('authority_created', 'counter', 1, metric_tags=dict(owner=authority.owner))
|
||||
return authority
|
||||
|
||||
|
||||
|
@ -167,7 +167,7 @@ class AuthoritiesList(AuthenticatedResource):
|
||||
:statuscode 403: unauthenticated
|
||||
:statuscode 200: no error
|
||||
"""
|
||||
return service.create(data)
|
||||
return service.create(**data)
|
||||
|
||||
|
||||
class Authorities(AuthenticatedResource):
|
||||
|
Reference in New Issue
Block a user