Ensuring that destinations require private keys by default. (#390)
* Ensuring that destinations require private keys by default.
This commit is contained in:
parent
4ee1c21144
commit
4077893d08
@ -137,6 +137,12 @@ Destination
|
||||
Destination plugins allow you to propagate certificates managed by Lemur to additional third parties. This provides flexibility when
|
||||
different orchestration systems have their own way of manage certificates or there is an existing system you wish to integrate with Lemur.
|
||||
|
||||
By default destination plugins have a private key requirement. If your plugin does not require a certificates private key mark `requires_key = False`
|
||||
in the plugins base class like so::
|
||||
|
||||
class MyDestinationPlugin(DestinationPlugin):
|
||||
requires_key = False
|
||||
|
||||
The DestinationPlugin requires only one function to be implemented::
|
||||
|
||||
def upload(self, cert, private_key, cert_chain, options, **kwargs):
|
||||
|
@ -11,6 +11,7 @@ from sqlalchemy import Column, Integer, String, Text, func, ForeignKey, DateTime
|
||||
from sqlalchemy.dialects.postgresql import JSON
|
||||
|
||||
from lemur.database import db
|
||||
from lemur.plugins.base import plugins
|
||||
from lemur.models import roles_authorities
|
||||
|
||||
|
||||
@ -38,3 +39,7 @@ class Authority(db.Model):
|
||||
self.description = kwargs.get('description')
|
||||
self.authority_certificate = kwargs['authority_certificate']
|
||||
self.plugin_name = kwargs['plugin']['slug']
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
return plugins.get(self.plugin_name)
|
||||
|
@ -158,6 +158,7 @@ def update_destinations(target, value, initiator):
|
||||
:return:
|
||||
"""
|
||||
destination_plugin = plugins.get(value.plugin_name)
|
||||
|
||||
try:
|
||||
destination_plugin.upload(target.name, target.body, target.private_key, target.chain, value.options)
|
||||
except Exception as e:
|
||||
|
@ -584,6 +584,11 @@ class Certificates(AuthenticatedResource):
|
||||
permission = CertificatePermission(cert.id, owner_role, [x.name for x in cert.roles])
|
||||
|
||||
if permission.can():
|
||||
for destination in data['destinations']:
|
||||
if destination.plugin.requires_key:
|
||||
if not cert.private_key:
|
||||
return dict('Unable to add destination: {0}. Certificate does not have required private key.'.format(destination.label))
|
||||
|
||||
return service.update(
|
||||
certificate_id,
|
||||
data['owner'],
|
||||
@ -871,10 +876,13 @@ class CertificateExport(AuthenticatedResource):
|
||||
plugin = data['plugin']['plugin_object']
|
||||
|
||||
if plugin.requires_key:
|
||||
if permission.can():
|
||||
extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, options)
|
||||
if cert.private_key:
|
||||
if permission.can():
|
||||
extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, options)
|
||||
else:
|
||||
return dict(message='You are not authorized to export this certificate'), 403
|
||||
else:
|
||||
return dict(message='You are not authorized to export this certificate'), 403
|
||||
return dict(message='Unable to export certificate, plugin: {0} requires a private key but no key was found.'.format(plugin.slug))
|
||||
else:
|
||||
extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, options)
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
:license: Apache, see LICENSE for more details.
|
||||
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
||||
"""
|
||||
import copy
|
||||
from sqlalchemy import Column, Integer, String, Text
|
||||
from sqlalchemy_utils import JSONType
|
||||
from lemur.database import db
|
||||
@ -23,7 +22,4 @@ class Destination(db.Model):
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
p = plugins.get(self.plugin_name)
|
||||
c = copy.deepcopy(p)
|
||||
c.options = self.options
|
||||
return c
|
||||
return plugins.get(self.plugin_name)
|
||||
|
@ -11,6 +11,7 @@ from lemur.plugins.base import Plugin
|
||||
|
||||
class DestinationPlugin(Plugin):
|
||||
type = 'destination'
|
||||
requires_key = True
|
||||
|
||||
def upload(self):
|
||||
raise NotImplemented
|
||||
|
@ -68,19 +68,16 @@ class AWSDestinationPlugin(DestinationPlugin):
|
||||
# }
|
||||
|
||||
def upload(self, name, body, private_key, cert_chain, options, **kwargs):
|
||||
if private_key:
|
||||
try:
|
||||
iam.upload_cert(self.get_option('accountNumber', options), name, body, private_key,
|
||||
cert_chain=cert_chain)
|
||||
except BotoServerError as e:
|
||||
if e.error_code != 'EntityAlreadyExists':
|
||||
raise Exception(e)
|
||||
try:
|
||||
iam.upload_cert(self.get_option('accountNumber', options), name, body, private_key,
|
||||
cert_chain=cert_chain)
|
||||
except BotoServerError as e:
|
||||
if e.error_code != 'EntityAlreadyExists':
|
||||
raise Exception(e)
|
||||
|
||||
e = self.get_option('elb', options)
|
||||
if e:
|
||||
attach_certificate(kwargs['accountNumber'], ['region'], e['name'], e['port'], e['certificateId'])
|
||||
else:
|
||||
raise Exception("Unable to upload to AWS, private key is required")
|
||||
e = self.get_option('elb', options)
|
||||
if e:
|
||||
attach_certificate(kwargs['accountNumber'], ['region'], e['name'], e['port'], e['certificateId'])
|
||||
|
||||
|
||||
class AWSSourcePlugin(SourcePlugin):
|
||||
|
@ -236,9 +236,6 @@ class JavaKeystoreExportPlugin(ExportPlugin):
|
||||
alias = "blah"
|
||||
|
||||
with mktemppath() as jks_tmp:
|
||||
if not key:
|
||||
raise Exception("Unable to export, no private key found.")
|
||||
|
||||
create_keystore(body, chain, jks_tmp, key, alias, passphrase)
|
||||
|
||||
with open(jks_tmp, 'rb') as f:
|
||||
|
@ -25,7 +25,7 @@ def test_authority_input_schema(client, role):
|
||||
assert not errors
|
||||
|
||||
|
||||
def test_user_authority(session, client, authority, role, user):
|
||||
def test_user_authority(session, client, authority, role, user, issuer_plugin):
|
||||
assert client.get(api.url_for(AuthoritiesList), headers=user['token']).json['total'] == 0
|
||||
u = user['user']
|
||||
u.roles.append(role)
|
||||
|
Loading…
Reference in New Issue
Block a user