[WIP] - 422 elb rotate (#493)

* Initial work on certificate rotation.

* Adding ability to get additional certificate info.

* - Adding endpoint rotation.
- Removes the g requirement from all services to enable easier testing.
This commit is contained in:
kevgliss
2016-11-18 11:27:46 -08:00
committed by GitHub
parent 6fd47edbe3
commit d45e7d6b85
27 changed files with 393 additions and 390 deletions

View File

@ -14,6 +14,7 @@ from lemur.sources.models import Source
from lemur.notifications.models import Notification
from lemur.users.models import User
from lemur.roles.models import Role
from lemur.endpoints.models import Policy, Endpoint
from .vectors import INTERNAL_VALID_SAN_STR, PRIVATE_KEY_STR
@ -227,6 +228,10 @@ class PolicyFactory(BaseFactory):
"""Policy Factory."""
name = Sequence(lambda n: 'endpoint{0}'.format(n))
class Meta:
"""Factory Configuration."""
model = Policy
class EndpointFactory(BaseFactory):
"""Endpoint Factory."""
@ -237,4 +242,8 @@ class EndpointFactory(BaseFactory):
port = FuzzyInteger(0, high=65535)
policy = SubFactory(PolicyFactory)
certificate = SubFactory(CertificateFactory)
destination = SubFactory(DestinationFactory)
source = SubFactory(SourceFactory)
class Meta:
"""Factory Configuration."""
model = Endpoint

View File

@ -14,3 +14,6 @@ class TestSourcePlugin(SourcePlugin):
def get_certificates(self):
return
def update_endpoint(self, endpoint, certificate):
return

View File

@ -37,9 +37,9 @@ def test_user_authority(session, client, authority, role, user, issuer_plugin):
assert client.get(api.url_for(AuthoritiesList), headers=user['token']).json['total'] == 0
def test_create_authority(issuer_plugin, logged_in_admin):
def test_create_authority(issuer_plugin, user):
from lemur.authorities.service import create
authority = create(plugin={'plugin_object': issuer_plugin, 'slug': issuer_plugin.slug}, owner='jim@example.com', type='root')
authority = create(plugin={'plugin_object': issuer_plugin, 'slug': issuer_plugin.slug}, owner='jim@example.com', type='root', creator=user['user'])
assert authority.authority_certificate
@ -47,7 +47,7 @@ def test_create_authority(issuer_plugin, logged_in_admin):
(VALID_USER_HEADER_TOKEN, 0),
(VALID_ADMIN_HEADER_TOKEN, 3)
])
def test_admin_authority(client, authority, token, count):
def test_admin_authority(client, authority, issuer_plugin, token, count):
assert client.get(api.url_for(AuthoritiesList), headers=token).json['total'] == count

View File

@ -30,13 +30,18 @@ def test_get_certificate_primitives(certificate):
},
'destinations': [],
'roles': [],
'validity_end': datetime.date(year=2021, month=5, day=7),
'validity_start': datetime.date(year=2016, month=10, day=30)
'validity_end': arrow.get(2021, 5, 7),
'validity_start': arrow.get(2016, 10, 30),
'country': 'US',
'location': 'A place',
'organization': 'Example',
'organizational_unit': 'Operations',
'state': 'CA'
}
with freeze_time(datetime.date(year=2016, month=10, day=30)):
primitives = get_certificate_primitives(certificate)
assert data == primitives
assert len(primitives) == 14
def test_certificate_edit_schema(session):
@ -354,18 +359,24 @@ def test_mint_certificate(issuer_plugin, authority, logged_in_admin):
assert cert_body == INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR
def test_create_certificate(issuer_plugin, authority, logged_in_admin):
def test_create_certificate(issuer_plugin, authority, user):
from lemur.certificates.service import create
cert = create(authority=authority, csr=CSR_STR, owner='joe@example.com')
assert str(cert.not_after) == '2040-01-01 20:30:52'
assert str(cert.not_before) == '2015-06-26 20:30:52'
cert = create(authority=authority, csr=CSR_STR, owner='joe@example.com', creator=user['user'])
assert str(cert.not_after) == '2040-01-01T20:30:52+00:00'
assert str(cert.not_before) == '2015-06-26T20:30:52+00:00'
assert cert.issuer == 'Example'
assert cert.name == 'long.lived.com-Example-20150626-20400101'
cert = create(authority=authority, csr=CSR_STR, owner='joe@example.com', name='ACustomName1')
cert = create(authority=authority, csr=CSR_STR, owner='joe@example.com', name='ACustomName1', creator=user['user'])
assert cert.name == 'ACustomName1'
def test_reissue_certificate(issuer_plugin, authority, certificate, logged_in_admin):
from lemur.certificates.service import reissue_certificate
new_cert = reissue_certificate(certificate)
assert new_cert
def test_create_csr():
from lemur.certificates.service import create_csr
@ -381,34 +392,34 @@ def test_create_csr():
assert private_key
def test_import(logged_in_user):
def test_import(user):
from lemur.certificates.service import import_certificate
cert = import_certificate(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR)
assert str(cert.not_after) == '2040-01-01 20:30:52'
assert str(cert.not_before) == '2015-06-26 20:30:52'
assert cert.issuer == 'Example'
assert cert.name == 'long.lived.com-Example-20150626-20400101-1'
cert = import_certificate(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName2')
assert cert.name == 'ACustomName2'
def test_upload(logged_in_user):
from lemur.certificates.service import upload
cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com')
assert str(cert.not_after) == '2040-01-01 20:30:52'
assert str(cert.not_before) == '2015-06-26 20:30:52'
cert = import_certificate(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, creator=user['user'])
assert str(cert.not_after) == '2040-01-01T20:30:52+00:00'
assert str(cert.not_before) == '2015-06-26T20:30:52+00:00'
assert cert.issuer == 'Example'
assert cert.name == 'long.lived.com-Example-20150626-20400101-2'
cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName')
cert = import_certificate(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName2', creator=user['user'])
assert cert.name == 'ACustomName2'
def test_upload(user):
from lemur.certificates.service import upload
cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', creator=user['user'])
assert str(cert.not_after) == '2040-01-01T20:30:52+00:00'
assert str(cert.not_before) == '2015-06-26T20:30:52+00:00'
assert cert.issuer == 'Example'
assert cert.name == 'long.lived.com-Example-20150626-20400101-3'
cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName', creator=user['user'])
assert 'ACustomName' in cert.name
# verify upload with a private key as a str
def test_upload_private_key_str(logged_in_user):
def test_upload_private_key_str(user):
from lemur.certificates.service import upload
cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR.decode('utf-8'), owner='joe@example.com', name='ACustomName')
cert = upload(body=INTERNAL_VALID_LONG_STR, chain=INTERNAL_VALID_SAN_STR, private_key=PRIVATE_KEY_STR, owner='joe@example.com', name='ACustomName', creator=user['user'])
assert cert

View File

@ -1,11 +1,21 @@
import pytest
from lemur.endpoints.views import * # noqa
from lemur.tests.factories import EndpointFactory, CertificateFactory
from .vectors import VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKEN
def test_rotate_certificate(client, source_plugin):
from lemur.endpoints.service import rotate_certificate
new_certificate = CertificateFactory()
endpoint = EndpointFactory()
rotate_certificate(endpoint, new_certificate)
assert endpoint.certificate == new_certificate
@pytest.mark.parametrize("token,status", [
(VALID_USER_HEADER_TOKEN, 404),
(VALID_ADMIN_HEADER_TOKEN, 404),

View File

@ -110,7 +110,7 @@ def test_role_put_with_data_and_user(client, session):
}
assert client.put(api.url_for(Roles, role_id=role.id), data=json.dumps(data), headers=headers).status_code == 200
assert client.get(api.url_for(RolesList), data={}, headers=headers).json['total'] == 1
assert client.get(api.url_for(RolesList), data={}, headers=headers).json['total'] > 1
@pytest.mark.parametrize("token,status", [

View File

@ -18,7 +18,7 @@ def validate_source_schema(client):
assert not errors
def test_create_certificate(source):
def test_create_certificate(user, source):
from lemur.sources.service import certificate_create
with pytest.raises(Exception):
@ -27,7 +27,8 @@ def test_create_certificate(source):
data = {
'body': INTERNAL_VALID_WILDCARD_STR,
'private_key': INTERNAL_PRIVATE_KEY_A_STR,
'owner': 'bob@example.com'
'owner': 'bob@example.com',
'creator': user['user']
}
cert = certificate_create(data, source)

View File

@ -8,7 +8,6 @@ def test_private_key(session):
from lemur.common.validators import private_key
private_key(PRIVATE_KEY_STR)
private_key(PRIVATE_KEY_STR.decode('utf-8'))
with pytest.raises(ValidationError):
private_key('invalid_private_key')

View File

@ -12,7 +12,7 @@ VALID_ADMIN_HEADER_TOKEN = {
}
INTERNAL_VALID_LONG_STR = b"""
INTERNAL_VALID_LONG_STR = """
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAkNBMRAwDgYDVQQHDAdBIHBsYWNlMRcwFQYDVQQDDA5sb25nLmxp
@ -40,7 +40,7 @@ h0S8LN4iv/+vNFPNiM1z9X/SZgfbwZXrLsSi
INTERNAL_VALID_LONG_CERT = parse_certificate(INTERNAL_VALID_LONG_STR)
INTERNAL_INVALID_STR = b"""
INTERNAL_INVALID_STR = """
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgICA+gwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5s
@ -69,7 +69,7 @@ kP+oGWtHvhteUAe8Gloo5NchZJ0/BqlYRCD5aAHcmbXRsDid9mO4ADU=
INTERNAL_INVALID_CERT = parse_certificate(INTERNAL_INVALID_STR)
INTERNAL_VALID_SAN_STR = b"""
INTERNAL_VALID_SAN_STR = """
-----BEGIN CERTIFICATE-----
MIIESjCCAzKgAwIBAgICA+kwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5s
@ -99,7 +99,7 @@ YBrY/duF15YpoMKAlFhDBh6R9/nb5kI2n3pY6I5h6LEYfLStazXbIu61M8zu9TM/
INTERNAL_VALID_SAN_CERT = parse_certificate(INTERNAL_VALID_SAN_STR)
INTERNAL_VALID_WILDCARD_STR = b"""
INTERNAL_VALID_WILDCARD_STR = """
-----BEGIN CERTIFICATE-----
MIIEHDCCAwSgAwIBAgICA+owDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQSBwbGFjZTEXMBUGA1UEAwwObG9uZy5s
@ -128,7 +128,7 @@ S0Xb3ZauZJQI7OdHeUPDRVq+8hcG77sopN9pEYrIH08oxvLX2US3GqrowjOxthRa
INTERNAL_VALID_WILDCARD_CERT = parse_certificate(INTERNAL_VALID_WILDCARD_STR)
EXTERNAL_VALID_STR = b"""
EXTERNAL_VALID_STR = """
-----BEGIN CERTIFICATE-----
MIIFHzCCBAegAwIBAgIQGFWCciDWzbOej/TbAJN0WzANBgkqhkiG9w0BAQsFADCB
pDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
@ -163,7 +163,7 @@ Bs63gULVCqWygt5KEbv990m/XGuRMaXuHzHCHB4v5LRM30FiFmqCzyD8d+btzW9B
EXTERNAL_CERT = parse_certificate(EXTERNAL_VALID_STR)
PRIVATE_KEY_STR = b"""
PRIVATE_KEY_STR = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAnEjM0cQevlDjT6mDMtTo8N1ovAyKbfVEp0ketCPC4hLkStms
q9ETIyyerARIMv4SEhKqS4E7HIg6ccGkwv1ja5E/b2jHMH4ht1dEXnfM2yh0Mwvk
@ -193,7 +193,7 @@ XKxcRgm/Va4QMEAnec0qXfdTVJaJiAW0bdKwKRRrrbwcTdNRGibdng==
-----END RSA PRIVATE KEY-----
"""
INTERNAL_CERTIFICATE_A_STR = b"""
INTERNAL_CERTIFICATE_A_STR = """
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzET
MBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJTG9zIEdhdG9zMRYwFAYDVQQK
@ -218,7 +218,7 @@ L0Ew8hy0GG3nZ6uXLW7q
"""
INTERNAL_PRIVATE_KEY_A_STR = b"""
INTERNAL_PRIVATE_KEY_A_STR = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAtkyvL6EqSgYSJX11635Hb8FBG/8Wey6C2KtG7M+GXvGCsSmf
NqQMeZdfW9Avxelkstp5/K+ilVJJ2TJRelu1yVUUkQcrP7imgf7CxKQAnPz2oXQI
@ -249,7 +249,7 @@ o6ynBW1bG+qfjx9GyThgudvRtB+0vTSShrT5GftLCyMtOiYSHkGEvMOGFBuowzoz
"""
CSR_STR = b"""
CSR_STR = """
-----BEGIN CERTIFICATE REQUEST-----
MIIC1zCCAb8CAQAwczEUMBIGA1UEAwwLQUNvbW1vbk5hbWUxFTATBgNVBAoMDG9y
Z2FuaXphdGlvbjEOMAwGA1UECwwFZ3VuaXQxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
@ -271,7 +271,7 @@ PiFAxlc0tVjlLqQ=
"""
CSR_PEM_STR = b"""
CSR_PEM_STR = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAzZ2PgKflffhIPzwLXe26tuw+7Q72y9dAMrDVEms8u4Cch3yc
hN6Il5tvM4xTc0UN+aobAhaVoPDN+haXT/XyBRvbFV1f8nvmDQZGdmkyYkZ2xK2X