[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:
@ -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
|
||||
|
@ -14,3 +14,6 @@ class TestSourcePlugin(SourcePlugin):
|
||||
|
||||
def get_certificates(self):
|
||||
return
|
||||
|
||||
def update_endpoint(self, endpoint, certificate):
|
||||
return
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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", [
|
||||
|
@ -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)
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user