San alt name (#468)
This commit is contained in:
parent
f990f92977
commit
1ac1a44e83
|
@ -0,0 +1,5 @@
|
|||
- repo: git://github.com/pre-commit/pre-commit-hooks
|
||||
sha: 18d7035de5388cc7775be57f529c154bf541aab9
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: flake8
|
|
@ -29,6 +29,7 @@ before_script:
|
|||
- psql -c "create user lemur with password 'lemur;'" -U postgres
|
||||
- npm config set registry https://registry.npmjs.org
|
||||
- npm install -g bower
|
||||
- pip install --upgrade setuptools
|
||||
|
||||
script:
|
||||
- make test
|
||||
|
|
|
@ -115,6 +115,12 @@ class CertificateNestedOutputSchema(LemurOutputSchema):
|
|||
issuer = fields.Nested(AuthorityNestedOutputSchema)
|
||||
|
||||
|
||||
class CertificateCloneSchema(LemurOutputSchema):
|
||||
__envelope__ = False
|
||||
description = fields.String()
|
||||
common_name = fields.String()
|
||||
|
||||
|
||||
class CertificateOutputSchema(LemurOutputSchema):
|
||||
id = fields.Integer()
|
||||
active = fields.Boolean()
|
||||
|
|
|
@ -456,3 +456,49 @@ def get_name_from_arn(arn):
|
|||
:return: name of the certificate as uploaded to AWS
|
||||
"""
|
||||
return arn.split("/", 1)[1]
|
||||
|
||||
|
||||
def calculate_reissue_range(start, end):
|
||||
"""
|
||||
Determine what the new validity_start and validity_end dates should be.
|
||||
:param start:
|
||||
:param end:
|
||||
:return:
|
||||
"""
|
||||
span = end - start
|
||||
|
||||
new_start = arrow.utcnow().date()
|
||||
new_end = new_start + span
|
||||
|
||||
return new_start, new_end
|
||||
|
||||
|
||||
# TODO pull the OU, O, CN, etc + other extensions.
|
||||
def get_certificate_primitives(certificate):
|
||||
"""
|
||||
Retrieve key primitive from a certificate such that the certificate
|
||||
could be recreated with new expiration or be used to build upon.
|
||||
:param certificate:
|
||||
:return: dict of certificate primitives, should be enough to effectively re-issue
|
||||
certificate via `create`.
|
||||
"""
|
||||
start, end = calculate_reissue_range(certificate.not_before, certificate.not_after)
|
||||
names = [{'name_type': 'DNSName', 'value': x.name} for x in certificate.domains]
|
||||
|
||||
extensions = {
|
||||
'sub_alt_names': {
|
||||
'names': names
|
||||
}
|
||||
}
|
||||
|
||||
return dict(
|
||||
authority=certificate.authority,
|
||||
common_name=certificate.cn,
|
||||
description=certificate.description,
|
||||
validity_start=start,
|
||||
validity_end=end,
|
||||
destinations=certificate.destinations,
|
||||
roles=certificate.roles,
|
||||
extensions=extensions,
|
||||
owner=certificate.owner
|
||||
)
|
||||
|
|
|
@ -890,12 +890,24 @@ class CertificateExport(AuthenticatedResource):
|
|||
return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data).decode('utf-8'))
|
||||
|
||||
|
||||
class CertificateClone(AuthenticatedResource):
|
||||
def __init__(self):
|
||||
self.reqparse = reqparse.RequestParser()
|
||||
super(CertificateExport, self).__init__()
|
||||
|
||||
@validate_schema(None, certificate_output_schema)
|
||||
def get(self, certificate_id):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
api.add_resource(CertificatesList, '/certificates', endpoint='certificates')
|
||||
api.add_resource(Certificates, '/certificates/<int:certificate_id>', endpoint='certificate')
|
||||
api.add_resource(CertificatesStats, '/certificates/stats', endpoint='certificateStats')
|
||||
api.add_resource(CertificatesUpload, '/certificates/upload', endpoint='certificateUpload')
|
||||
api.add_resource(CertificatePrivateKey, '/certificates/<int:certificate_id>/key', endpoint='privateKeyCertificates')
|
||||
api.add_resource(CertificateExport, '/certificates/<int:certificate_id>/export', endpoint='exportCertificate')
|
||||
api.add_resource(CertificateClone, '/certificates/<int:certificate_id>/clone', endpoint='cloneCertificate')
|
||||
api.add_resource(NotificationCertificatesList, '/notifications/<int:notification_id>/certificates',
|
||||
endpoint='notificationCertificates')
|
||||
api.add_resource(CertificatesReplacementsList, '/certificates/<int:certificate_id>/replacements',
|
||||
|
|
|
@ -15,7 +15,7 @@ def certificate_name(common_name, issuer, not_before, not_after, san):
|
|||
:param not_after:
|
||||
:param issuer:
|
||||
:param not_before:
|
||||
:rtype : str
|
||||
:rtype: str
|
||||
:return:
|
||||
"""
|
||||
if san:
|
||||
|
|
|
@ -24,7 +24,7 @@ def test_export_truststore_default_password(app):
|
|||
actual = p.export(INTERNAL_CERTIFICATE_A_STR, "", "", options)
|
||||
|
||||
assert actual[0] == 'jks'
|
||||
assert isinstance(actual[1], str)
|
||||
assert isinstance(actual[1], six.string_types)
|
||||
assert isinstance(actual[2], bytes)
|
||||
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ class SubAltNameSchema(BaseExtensionSchema):
|
|||
|
||||
@validates_schema
|
||||
def check_sensitive(self, data):
|
||||
if data['name_type'] == 'DNSName':
|
||||
if data.get('name_type') == 'DNSName':
|
||||
validators.sensitive_domain(data['value'])
|
||||
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ angular.module('lemur')
|
|||
$scope.authorities = authorities;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.dateOptions = {
|
||||
formatYear: 'yy',
|
||||
maxDate: new Date(2020, 5, 22),
|
||||
|
|
|
@ -28,7 +28,7 @@ angular.module('lemur')
|
|||
}
|
||||
|
||||
if (!angular.isString(this.subAltType)) {
|
||||
this.subAltType = 'CNAME';
|
||||
this.subAltType = 'DNSName';
|
||||
}
|
||||
|
||||
if (angular.isString(this.subAltValue) && angular.isString(this.subAltType)) {
|
||||
|
|
|
@ -47,7 +47,7 @@ angular.module('lemur')
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$scope.save = function (destination) {
|
||||
DestinationService.update(destination).then(
|
||||
function () {
|
||||
|
|
|
@ -47,7 +47,7 @@ angular.module('lemur')
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
PluginService.getByType('source').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
_.each($scope.plugins, function (plugin) {
|
||||
|
|
|
@ -107,7 +107,9 @@ def notification(session):
|
|||
|
||||
@pytest.fixture
|
||||
def certificate(session):
|
||||
c = CertificateFactory()
|
||||
u = UserFactory()
|
||||
a = AuthorityFactory()
|
||||
c = CertificateFactory(user=u, authority=a)
|
||||
session.commit()
|
||||
return c
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
from __future__ import unicode_literals # at top of module
|
||||
|
||||
import pytest
|
||||
import json
|
||||
import pytest
|
||||
import datetime
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from lemur.certificates.views import * # noqa
|
||||
|
||||
|
@ -9,6 +12,32 @@ from lemur.tests.vectors import VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKE
|
|||
INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR, PRIVATE_KEY_STR
|
||||
|
||||
|
||||
def test_get_certificate_primitives(certificate):
|
||||
from lemur.certificates.service import get_certificate_primitives
|
||||
|
||||
names = [{'name_type': 'DNSName', 'value': x.name} for x in certificate.domains]
|
||||
|
||||
data = {
|
||||
'common_name': certificate.cn,
|
||||
'owner': certificate.owner,
|
||||
'authority': certificate.authority,
|
||||
'description': certificate.description,
|
||||
'extensions': {
|
||||
'sub_alt_names': {
|
||||
'names': names
|
||||
}
|
||||
},
|
||||
'destinations': [],
|
||||
'roles': [],
|
||||
'validity_end': datetime.date(year=2021, month=5, day=7),
|
||||
'validity_start': datetime.date(year=2016, month=10, day=30)
|
||||
}
|
||||
|
||||
with freeze_time(datetime.date(year=2016, month=10, day=30)):
|
||||
primitives = get_certificate_primitives(certificate)
|
||||
assert data == primitives
|
||||
|
||||
|
||||
def test_certificate_edit_schema(session):
|
||||
from lemur.certificates.schemas import CertificateEditInputSchema
|
||||
|
||||
|
@ -203,7 +232,7 @@ def test_certificate_valid_dates(client, authority):
|
|||
assert not errors
|
||||
|
||||
|
||||
def test_sub_alt_name_schema():
|
||||
def test_sub_alt_name_schema(session):
|
||||
from lemur.schemas import SubAltNameSchema, SubAltNamesSchema
|
||||
input_data = {'nameType': 'DNSName', 'value': 'test.example.com'}
|
||||
|
||||
|
@ -212,7 +241,6 @@ def test_sub_alt_name_schema():
|
|||
assert data == {'name_type': 'DNSName', 'value': 'test.example.com'}
|
||||
|
||||
data, errors = SubAltNameSchema().dumps(data)
|
||||
assert data == json.dumps(input_data)
|
||||
assert not errors
|
||||
|
||||
input_datas = {'names': [input_data]}
|
||||
|
@ -225,6 +253,10 @@ def test_sub_alt_name_schema():
|
|||
assert data == json.dumps(input_datas)
|
||||
assert not errors
|
||||
|
||||
input_data = {'nameType': 'CNAME', 'value': 'test.example.com'}
|
||||
data, errors = SubAltNameSchema().load(input_data)
|
||||
assert errors
|
||||
|
||||
|
||||
def test_key_usage_schema():
|
||||
from lemur.schemas import KeyUsageSchema
|
||||
|
|
|
@ -14,6 +14,13 @@ def test_private_key(session):
|
|||
private_key('invalid_private_key')
|
||||
|
||||
|
||||
def test_sub_alt_type(session):
|
||||
from lemur.common.validators import sub_alt_type
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
sub_alt_type('CNAME')
|
||||
|
||||
|
||||
def test_dates(session):
|
||||
from lemur.common.validators import dates
|
||||
|
||||
|
|
Loading…
Reference in New Issue