parent
c11034b9bc
commit
62b61ed980
|
@ -80,6 +80,21 @@ class AuthorityOutputSchema(LemurOutputSchema):
|
||||||
options = fields.Dict()
|
options = fields.Dict()
|
||||||
roles = fields.List(fields.Nested(AssociatedRoleSchema))
|
roles = fields.List(fields.Nested(AssociatedRoleSchema))
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorityNestedOutputSchema(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()
|
||||||
|
|
||||||
|
|
||||||
authority_update_schema = AuthorityUpdateSchema()
|
authority_update_schema = AuthorityUpdateSchema()
|
||||||
authority_input_schema = AuthorityInputSchema()
|
authority_input_schema = AuthorityInputSchema()
|
||||||
authority_output_schema = AuthorityOutputSchema()
|
authority_output_schema = AuthorityOutputSchema()
|
||||||
|
|
|
@ -12,6 +12,13 @@ from marshmallow.exceptions import ValidationError
|
||||||
|
|
||||||
from lemur.schemas import AssociatedAuthoritySchema, AssociatedDestinationSchema, AssociatedCertificateSchema, \
|
from lemur.schemas import AssociatedAuthoritySchema, AssociatedDestinationSchema, AssociatedCertificateSchema, \
|
||||||
AssociatedNotificationSchema, PluginInputSchema, ExtensionSchema
|
AssociatedNotificationSchema, PluginInputSchema, ExtensionSchema
|
||||||
|
|
||||||
|
from lemur.authorities.schemas import AuthorityNestedOutputSchema
|
||||||
|
from lemur.destinations.schemas import DestinationNestedOutputSchema
|
||||||
|
from lemur.notifications.schemas import NotificationNestedOutputSchema
|
||||||
|
# from lemur.domains.schemas import DomainNestedOutputSchema
|
||||||
|
from lemur.users.schemas import UserNestedOutputSchema
|
||||||
|
|
||||||
from lemur.common.schema import LemurInputSchema, LemurOutputSchema
|
from lemur.common.schema import LemurInputSchema, LemurOutputSchema
|
||||||
from lemur.common import validators
|
from lemur.common import validators
|
||||||
|
|
||||||
|
@ -47,6 +54,33 @@ class CertificateInputSchema(LemurInputSchema):
|
||||||
validators.dates(data)
|
validators.dates(data)
|
||||||
|
|
||||||
|
|
||||||
|
class CertificateEditInputSchema(LemurInputSchema):
|
||||||
|
owner = fields.Email(required=True)
|
||||||
|
description = fields.String()
|
||||||
|
active = fields.Boolean()
|
||||||
|
destinations = fields.Nested(AssociatedDestinationSchema, missing=[], many=True)
|
||||||
|
notifications = fields.Nested(AssociatedNotificationSchema, missing=[], many=True)
|
||||||
|
replacements = fields.Nested(AssociatedCertificateSchema, missing=[], many=True)
|
||||||
|
|
||||||
|
|
||||||
|
class CertificateNestedOutputSchema(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()
|
||||||
|
creator = fields.Nested(UserNestedOutputSchema)
|
||||||
|
issuer = fields.Nested(AuthorityNestedOutputSchema)
|
||||||
|
|
||||||
|
|
||||||
class CertificateOutputSchema(LemurOutputSchema):
|
class CertificateOutputSchema(LemurOutputSchema):
|
||||||
id = fields.Integer()
|
id = fields.Integer()
|
||||||
active = fields.Boolean()
|
active = fields.Boolean()
|
||||||
|
@ -57,7 +91,7 @@ class CertificateOutputSchema(LemurOutputSchema):
|
||||||
description = fields.String()
|
description = fields.String()
|
||||||
issuer = fields.String()
|
issuer = fields.String()
|
||||||
name = fields.String()
|
name = fields.String()
|
||||||
common_name = fields.String()
|
cn = fields.String()
|
||||||
not_after = fields.DateTime()
|
not_after = fields.DateTime()
|
||||||
not_before = fields.DateTime()
|
not_before = fields.DateTime()
|
||||||
owner = fields.Email()
|
owner = fields.Email()
|
||||||
|
@ -65,6 +99,12 @@ class CertificateOutputSchema(LemurOutputSchema):
|
||||||
serial = fields.String()
|
serial = fields.String()
|
||||||
signing_algorithm = fields.String()
|
signing_algorithm = fields.String()
|
||||||
status = fields.Boolean()
|
status = fields.Boolean()
|
||||||
|
user = fields.Nested(UserNestedOutputSchema)
|
||||||
|
# domains = fields.Nested(DomainNestedOutputSchema)
|
||||||
|
destinations = fields.Nested(DestinationNestedOutputSchema, many=True)
|
||||||
|
notifications = fields.Nested(NotificationNestedOutputSchema, many=True)
|
||||||
|
replaces = fields.Nested(CertificateNestedOutputSchema, many=True)
|
||||||
|
authority = fields.Nested(AuthorityNestedOutputSchema)
|
||||||
|
|
||||||
|
|
||||||
class CertificateUploadInputSchema(LemurInputSchema):
|
class CertificateUploadInputSchema(LemurInputSchema):
|
||||||
|
@ -97,3 +137,4 @@ certificate_output_schema = CertificateOutputSchema()
|
||||||
certificates_output_schema = CertificateOutputSchema(many=True)
|
certificates_output_schema = CertificateOutputSchema(many=True)
|
||||||
certificate_upload_input_schema = CertificateUploadInputSchema()
|
certificate_upload_input_schema = CertificateUploadInputSchema()
|
||||||
certificate_export_input_schema = CertificateExportInputSchema()
|
certificate_export_input_schema = CertificateExportInputSchema()
|
||||||
|
certificate_edit_input_schema = CertificateEditInputSchema()
|
||||||
|
|
|
@ -19,7 +19,7 @@ from lemur.auth.permissions import ViewKeyPermission, AuthorityPermission, Updat
|
||||||
|
|
||||||
from lemur.certificates import service
|
from lemur.certificates import service
|
||||||
from lemur.certificates.schemas import certificate_input_schema, certificate_output_schema, \
|
from lemur.certificates.schemas import certificate_input_schema, certificate_output_schema, \
|
||||||
certificate_upload_input_schema, certificates_output_schema, certificate_export_input_schema
|
certificate_upload_input_schema, certificates_output_schema, certificate_export_input_schema, certificate_edit_input_schema
|
||||||
|
|
||||||
from lemur.roles import service as role_service
|
from lemur.roles import service as role_service
|
||||||
|
|
||||||
|
@ -464,7 +464,7 @@ class Certificates(AuthenticatedResource):
|
||||||
"""
|
"""
|
||||||
return service.get(certificate_id)
|
return service.get(certificate_id)
|
||||||
|
|
||||||
@validate_schema(certificate_upload_input_schema, certificate_output_schema)
|
@validate_schema(certificate_edit_input_schema, certificate_output_schema)
|
||||||
def put(self, certificate_id, data=None):
|
def put(self, certificate_id, data=None):
|
||||||
"""
|
"""
|
||||||
.. http:put:: /certificates/1
|
.. http:put:: /certificates/1
|
||||||
|
|
|
@ -33,6 +33,10 @@ class DestinationOutputSchema(LemurOutputSchema):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class DestinationNestedOutputSchema(DestinationOutputSchema):
|
||||||
|
__envelope__ = False
|
||||||
|
|
||||||
|
|
||||||
destination_input_schema = DestinationInputSchema()
|
destination_input_schema = DestinationInputSchema()
|
||||||
destinations_output_schema = DestinationOutputSchema(many=True)
|
destinations_output_schema = DestinationOutputSchema(many=True)
|
||||||
destination_output_schema = DestinationOutputSchema()
|
destination_output_schema = DestinationOutputSchema()
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
"""
|
||||||
|
.. module: lemur.domains.schemas
|
||||||
|
:platform: unix
|
||||||
|
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
|
||||||
|
:license: Apache, see LICENSE for more details.
|
||||||
|
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
||||||
|
"""
|
||||||
|
from marshmallow import fields
|
||||||
|
from lemur.common.schema import LemurInputSchema, LemurOutputSchema
|
||||||
|
from lemur.schemas import AssociatedCertificateSchema
|
||||||
|
|
||||||
|
from lemur.certificates.schemas import CertificateNestedOutputSchema
|
||||||
|
|
||||||
|
|
||||||
|
class DomainInputSchema(LemurInputSchema):
|
||||||
|
id = fields.Integer()
|
||||||
|
name = fields.String(required=True)
|
||||||
|
sensitive = fields.Boolean()
|
||||||
|
certificates = fields.Nested(AssociatedCertificateSchema, many=True, missing=[])
|
||||||
|
|
||||||
|
|
||||||
|
class DomainOutputSchema(LemurOutputSchema):
|
||||||
|
id = fields.Integer()
|
||||||
|
name = fields.String()
|
||||||
|
sensitive = fields.Boolean()
|
||||||
|
certificates = fields.Nested(CertificateNestedOutputSchema, many=True, missing=[])
|
||||||
|
|
||||||
|
|
||||||
|
class DomainNestedOutputSchema(DomainOutputSchema):
|
||||||
|
__envelope__ = False
|
||||||
|
|
||||||
|
|
||||||
|
domain_input_schema = DomainInputSchema()
|
||||||
|
domain_output_schema = DomainOutputSchema()
|
||||||
|
domains_output_schema = DomainOutputSchema(many=True)
|
|
@ -77,11 +77,6 @@ def render(args):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
query = database.session_query(Domain).join(Certificate, Domain.certificate)
|
query = database.session_query(Domain).join(Certificate, Domain.certificate)
|
||||||
|
|
||||||
sort_by = args.pop('sort_by')
|
|
||||||
sort_dir = args.pop('sort_dir')
|
|
||||||
page = args.pop('page')
|
|
||||||
count = args.pop('count')
|
|
||||||
filt = args.pop('filter')
|
filt = args.pop('filter')
|
||||||
certificate_id = args.pop('certificate_id', None)
|
certificate_id = args.pop('certificate_id', None)
|
||||||
|
|
||||||
|
@ -92,9 +87,4 @@ def render(args):
|
||||||
if certificate_id:
|
if certificate_id:
|
||||||
query = query.filter(Certificate.id == certificate_id)
|
query = query.filter(Certificate.id == certificate_id)
|
||||||
|
|
||||||
query = database.find_all(query, Domain, args)
|
return database.sort_and_page(query, Domain, args)
|
||||||
|
|
||||||
if sort_by and sort_dir:
|
|
||||||
query = database.sort(query, Domain, sort_by, sort_dir)
|
|
||||||
|
|
||||||
return database.paginate(query, page, count)
|
|
||||||
|
|
|
@ -8,19 +8,16 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
from flask.ext.restful import reqparse, Api, fields
|
from flask.ext.restful import reqparse, Api
|
||||||
|
|
||||||
from lemur.domains import service
|
from lemur.domains import service
|
||||||
from lemur.auth.service import AuthenticatedResource
|
from lemur.auth.service import AuthenticatedResource
|
||||||
from lemur.auth.permissions import SensitiveDomainPermission
|
from lemur.auth.permissions import SensitiveDomainPermission
|
||||||
|
|
||||||
from lemur.common.utils import paginated_parser, marshal_items
|
from lemur.common.schema import validate_schema
|
||||||
|
from lemur.common.utils import paginated_parser
|
||||||
|
|
||||||
FIELDS = {
|
from lemur.domains.schemas import domain_input_schema, domain_output_schema, domains_output_schema
|
||||||
'id': fields.Integer,
|
|
||||||
'name': fields.String,
|
|
||||||
'sensitive': fields.Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
mod = Blueprint('domains', __name__)
|
mod = Blueprint('domains', __name__)
|
||||||
api = Api(mod)
|
api = Api(mod)
|
||||||
|
@ -31,7 +28,7 @@ class DomainsList(AuthenticatedResource):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(DomainsList, self).__init__()
|
super(DomainsList, self).__init__()
|
||||||
|
|
||||||
@marshal_items(FIELDS)
|
@validate_schema(None, domains_output_schema)
|
||||||
def get(self):
|
def get(self):
|
||||||
"""
|
"""
|
||||||
.. http:get:: /domains
|
.. http:get:: /domains
|
||||||
|
@ -83,8 +80,8 @@ class DomainsList(AuthenticatedResource):
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return service.render(args)
|
return service.render(args)
|
||||||
|
|
||||||
@marshal_items(FIELDS)
|
@validate_schema(domain_input_schema, domain_output_schema)
|
||||||
def post(self):
|
def post(self, data=None):
|
||||||
"""
|
"""
|
||||||
.. http:post:: /domains
|
.. http:post:: /domains
|
||||||
|
|
||||||
|
@ -126,10 +123,7 @@ class DomainsList(AuthenticatedResource):
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 403: unauthenticated
|
:statuscode 403: unauthenticated
|
||||||
"""
|
"""
|
||||||
self.reqparse.add_argument('name', type=str, location='json')
|
return service.create(data['name'], data['sensitive'])
|
||||||
self.reqparse.add_argument('sensitive', type=bool, default=False, location='json')
|
|
||||||
args = self.reqparse.parse_args()
|
|
||||||
return service.create(args['name'], args['sensitive'])
|
|
||||||
|
|
||||||
|
|
||||||
class Domains(AuthenticatedResource):
|
class Domains(AuthenticatedResource):
|
||||||
|
@ -137,7 +131,7 @@ class Domains(AuthenticatedResource):
|
||||||
self.reqparse = reqparse.RequestParser()
|
self.reqparse = reqparse.RequestParser()
|
||||||
super(Domains, self).__init__()
|
super(Domains, self).__init__()
|
||||||
|
|
||||||
@marshal_items(FIELDS)
|
@validate_schema(None, domain_output_schema)
|
||||||
def get(self, domain_id):
|
def get(self, domain_id):
|
||||||
"""
|
"""
|
||||||
.. http:get:: /domains/1
|
.. http:get:: /domains/1
|
||||||
|
@ -172,8 +166,8 @@ class Domains(AuthenticatedResource):
|
||||||
"""
|
"""
|
||||||
return service.get(domain_id)
|
return service.get(domain_id)
|
||||||
|
|
||||||
@marshal_items(FIELDS)
|
@validate_schema(domain_input_schema, domain_output_schema)
|
||||||
def put(self, domain_id):
|
def put(self, domain_id, data=None):
|
||||||
"""
|
"""
|
||||||
.. http:get:: /domains/1
|
.. http:get:: /domains/1
|
||||||
|
|
||||||
|
@ -210,12 +204,8 @@ class Domains(AuthenticatedResource):
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 403: unauthenticated
|
:statuscode 403: unauthenticated
|
||||||
"""
|
"""
|
||||||
self.reqparse.add_argument('name', type=str, location='json')
|
|
||||||
self.reqparse.add_argument('sensitive', type=bool, default=False, location='json')
|
|
||||||
args = self.reqparse.parse_args()
|
|
||||||
|
|
||||||
if SensitiveDomainPermission().can():
|
if SensitiveDomainPermission().can():
|
||||||
return service.update(domain_id, args['name'], args['sensitive'])
|
return service.update(domain_id, data['name'], data['sensitive'])
|
||||||
|
|
||||||
return dict(message='You are not authorized to modify this domain'), 403
|
return dict(message='You are not authorized to modify this domain'), 403
|
||||||
|
|
||||||
|
@ -225,7 +215,7 @@ class CertificateDomains(AuthenticatedResource):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CertificateDomains, self).__init__()
|
super(CertificateDomains, self).__init__()
|
||||||
|
|
||||||
@marshal_items(FIELDS)
|
@validate_schema(None, domains_output_schema)
|
||||||
def get(self, certificate_id):
|
def get(self, certificate_id):
|
||||||
"""
|
"""
|
||||||
.. http:get:: /certificates/1/domains
|
.. http:get:: /certificates/1/domains
|
||||||
|
|
|
@ -34,6 +34,10 @@ class NotificationOutputSchema(LemurOutputSchema):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationNestedOutputSchema(NotificationOutputSchema):
|
||||||
|
__envelope__ = False
|
||||||
|
|
||||||
|
|
||||||
notification_input_schema = NotificationInputSchema()
|
notification_input_schema = NotificationInputSchema()
|
||||||
notification_output_schema = NotificationOutputSchema()
|
notification_output_schema = NotificationOutputSchema()
|
||||||
notifications_output_schema = NotificationOutputSchema(many=True)
|
notifications_output_schema = NotificationOutputSchema(many=True)
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
uib-tooltip="Roles control which authorities a user can issue certificates from"
|
uib-tooltip="Roles control which authorities a user can issue certificates from"
|
||||||
tooltip-trigger="focus" tooltip-placement="top">
|
tooltip-trigger="focus" tooltip-placement="top">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="roles.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
<button ng-model="roles.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||||
<span class="badge">{{ authority.roles.length || 0 }}</span>
|
<span class="badge">{{ authority.roles.length || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
uib-tooltip="These are the User roles you wish to associated with your authority"
|
uib-tooltip="These are the User roles you wish to associated with your authority"
|
||||||
tooltip-trigger="focus" tooltip-placement="top">
|
tooltip-trigger="focus" tooltip-placement="top">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="roles.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
<button ng-model="roles.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||||
<span class="badge">{{ authority.roles.length || 0 }}</span>
|
<span class="badge">{{ authority.roles.length || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
uib-tooltip-trigger="focus" uib-tooltip-placement="top"
|
uib-tooltip-trigger="focus" uib-tooltip-placement="top"
|
||||||
typeahead-wait-ms="500">
|
typeahead-wait-ms="500">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="destinations.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
<button ng-model="destinations.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||||
<span class="badge">{{ certificate.destinations.length || 0 }}</span>
|
<span class="badge">{{ certificate.destinations.length || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
uib-tooltip="By default Lemur will always notify you about this certificate through Email notifications."
|
uib-tooltip="By default Lemur will always notify you about this certificate through Email notifications."
|
||||||
uib-tooltip-trigger="focus" tooltip-placement="top" typeahead-wait-ms="500">
|
uib-tooltip-trigger="focus" tooltip-placement="top" typeahead-wait-ms="500">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="notifications.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
<button ng-model="notifications.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||||
<span class="badge">{{ certificate.notifications.length || 0 }}</span>
|
<span class="badge">{{ certificate.notifications.length || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
uib-tooltip="Lemur will mark any certificates being replaced as 'inactive'"
|
uib-tooltip="Lemur will mark any certificates being replaced as 'inactive'"
|
||||||
uib-tooltip-trigger="focus" uib-tooltip-placement="top" typeahead-wait-ms="500">
|
uib-tooltip-trigger="focus" uib-tooltip-placement="top" typeahead-wait-ms="500">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="replacements.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
<button ng-model="replacements.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||||
<span class="badge">{{ certificate.replacements.length || 0 }}</span>
|
<span class="badge">{{ certificate.replacements.length || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -31,15 +31,6 @@ angular.module('lemur')
|
||||||
getData: function ($defer, params) {
|
getData: function ($defer, params) {
|
||||||
CertificateApi.getList(params.url())
|
CertificateApi.getList(params.url())
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
// TODO we should attempt to resolve all of these in parallel
|
|
||||||
_.each(data, function (certificate) {
|
|
||||||
CertificateService.getDomains(certificate);
|
|
||||||
CertificateService.getDestinations(certificate);
|
|
||||||
CertificateService.getNotifications(certificate);
|
|
||||||
CertificateService.getReplacements(certificate);
|
|
||||||
CertificateService.getAuthority(certificate);
|
|
||||||
CertificateService.getCreator(certificate);
|
|
||||||
});
|
|
||||||
params.total(data.total);
|
params.total(data.total);
|
||||||
$defer.resolve(data);
|
$defer.resolve(data);
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,14 +37,14 @@
|
||||||
<td data-title="'Issuer'" sortable="'issuer'" filter="{ 'issuer': 'text' }">
|
<td data-title="'Issuer'" sortable="'issuer'" filter="{ 'issuer': 'text' }">
|
||||||
{{ certificate.authority.name || certificate.issuer }}
|
{{ certificate.authority.name || certificate.issuer }}
|
||||||
</td>
|
</td>
|
||||||
<td data-title="'Domains'" filter="{ 'cn': 'text'}">
|
<td data-title="'Common Name'" filter="{ 'cn': 'text'}">
|
||||||
{{ certificate.cn }}
|
{{ certificate.cn }}
|
||||||
</td>
|
</td>
|
||||||
<td class="col-md-2" data-title="''">
|
<td class="col-md-2" data-title="''">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<a class="btn btn-sm btn-default" ui-sref="certificate({name: certificate.name})">Permalink</a>
|
<a class="btn btn-sm btn-default" ui-sref="certificate({name: certificate.name})">Permalink</a>
|
||||||
<button ng-model="certificate.toggle" class="btn btn-sm btn-info" btn-checkbox btn-checkbox-true="1"
|
<button ng-model="certificate.toggle" class="btn btn-sm btn-info" uib-btn-checkbox btn-checkbox-true="1"
|
||||||
butn-checkbox-false="0">More
|
btn-checkbox-false="0">More
|
||||||
</button>
|
</button>
|
||||||
<button ng-click="export(certificate.id)" class="btn btn-sm btn-success">
|
<button ng-click="export(certificate.id)" class="btn btn-sm btn-success">
|
||||||
Export
|
Export
|
||||||
|
@ -54,15 +54,15 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="warning" ng-if="certificate.toggle" ng-repeat-end>
|
<tr class="warning" ng-if="certificate.toggle" ng-repeat-end>
|
||||||
<td colspan="6">
|
<td colspan="12">
|
||||||
<tabset justified="true" class="col-md-6">
|
<uib-tabset justified="true" class="col-md-6">
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>Basic Info</tab-heading>
|
<uib-tab-heading>Basic Info</uib-tab-heading>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<strong>Creator</strong>
|
<strong>Creator</strong>
|
||||||
<span class="pull-right">
|
<span class="pull-right">
|
||||||
{{ certificate.creator.email }}
|
{{ certificate.user.email }}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
|
@ -111,71 +111,71 @@
|
||||||
<p>{{ certificate.description }}</p>
|
<p>{{ certificate.description }}</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</tab>
|
</uib-tab>
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>Notifications</tab-heading>
|
<uib-tab-heading>Notifications</uib-tab-heading>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-item" ng-repeat="notification in certificate.notifications">
|
<li class="list-group-item" ng-repeat="notification in certificate.notifications">
|
||||||
<strong>{{ notification.label }}</strong>
|
<strong>{{ notification.label }}</strong>
|
||||||
<span class="pull-right">{{ notification.description}}</span>
|
<span class="pull-right">{{ notification.description}}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</tab>
|
</uib-tab>
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>Destinations</tab-heading>
|
<uib-tab-heading>Destinations</uib-tab-heading>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-item" ng-repeat="destination in certificate.destinations">
|
<li class="list-group-item" ng-repeat="destination in certificate.destinations">
|
||||||
<strong>{{ destination.label }}</strong>
|
<strong>{{ destination.label }}</strong>
|
||||||
<span class="pull-right">{{ destination.description }}</span>
|
<span class="pull-right">{{ destination.description }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</tab>
|
</uib-tab>
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>Domains</tab-heading>
|
<uib-tab-heading>Domains</uib-tab-heading>
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<a href="#/domains/{{ domain.id }}" class="list-group-item"
|
<a href="#/domains/{{ domain.id }}" class="list-group-item"
|
||||||
ng-repeat="domain in certificate.domains">{{ domain.name }}</a>
|
ng-repeat="domain in certificate.domains">{{ domain.name }}</a>
|
||||||
</div>
|
</div>
|
||||||
</tab>
|
</uib-tab>
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>Replaces</tab-heading>
|
<uib-tab-heading>Replaces</uib-tab-heading>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-item" ng-repeat="replacement in certificate.replacements">
|
<li class="list-group-item" ng-repeat="replacement in certificate.replaces">
|
||||||
<strong>{{ replacement.name }}</strong>
|
<strong>{{ replacement.name }}</strong>
|
||||||
<p>{{ replacement.description}}</p>
|
<p>{{ replacement.description}}</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</tab>
|
</uib-tab>
|
||||||
</tabset>
|
</uib-tabset>
|
||||||
<tabset justified="true" class="col-md-6">
|
<uib-tabset justified="true" class="col-md-6">
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>
|
<uib-tab-heading>
|
||||||
Chain
|
Chain
|
||||||
<button class="btn btn-xs btn-default clipboard-btn glyphicon glyphicon-copy"
|
<button class="btn btn-xs btn-default clipboard-btn glyphicon glyphicon-copy"
|
||||||
uib-tooltip="Copy chain to clipboard" tooltip-trigger="mouseenter" clipboard
|
uib-tooltip="Copy chain to clipboard" tooltip-trigger="mouseenter" clipboard
|
||||||
text="certificate.chain"></button>
|
text="certificate.chain"></button>
|
||||||
</tab-heading>
|
</uib-tab-heading>
|
||||||
<pre style="width: 100%">{{ certificate.chain }}</pre>
|
<pre style="width: 100%">{{ certificate.chain }}</pre>
|
||||||
</tab>
|
</uib-tab>
|
||||||
<tab>
|
<uib-tab>
|
||||||
<tab-heading>
|
<uib-tab-heading>
|
||||||
Public Certificate
|
Public Certificate
|
||||||
<button class="btn btn-xs btn-default clipboard-btn glyphicon glyphicon-copy"
|
<button class="btn btn-xs btn-default clipboard-btn glyphicon glyphicon-copy"
|
||||||
uib-tooltip="Copy certificate to clipboard" tooltip-trigger="mouseenter" clipboard
|
uib-tooltip="Copy certificate to clipboard" tooltip-trigger="mouseenter" clipboard
|
||||||
text="certificate.body"></button>
|
text="certificate.body"></button>
|
||||||
</tab-heading>
|
</uib-tab-heading>
|
||||||
<pre style="width: 100%">{{ certificate.body }}</pre>
|
<pre style="width: 100%">{{ certificate.body }}</pre>
|
||||||
</tab>
|
</uib-tab>
|
||||||
<tab ng-click="loadPrivateKey(certificate)">
|
<uib-tab ng-click="loadPrivateKey(certificate)">
|
||||||
<tab-heading>
|
<uib-tab-heading>
|
||||||
Private Key
|
Private Key
|
||||||
<button class="btn btn-xs btn-default clipboard-btn glyphicon glyphicon-copy"
|
<button class="btn btn-xs btn-default clipboard-btn glyphicon glyphicon-copy"
|
||||||
uib-tooltip="Copy key to clipboard" tooltip-trigger="mouseenter" clipboard
|
uib-tooltip="Copy key to clipboard" tooltip-trigger="mouseenter" clipboard
|
||||||
text="certificate.privateKey"></button>
|
text="certificate.privateKey"></button>
|
||||||
</tab-heading>
|
</uib-tab-heading>
|
||||||
<pre style="width: 100%">{{ certificate.privateKey }}</pre>
|
<pre style="width: 100%">{{ certificate.privateKey }}</pre>
|
||||||
</tab>
|
</uib-tab>
|
||||||
</tabset>
|
</uib-tabset>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
uib-typeahead="certificate.name for certificate in certificateService.findCertificatesByName($viewValue)" typeahead-loading="loadingCertificates"
|
uib-typeahead="certificate.name for certificate in certificateService.findCertificatesByName($viewValue)" typeahead-loading="loadingCertificates"
|
||||||
class="form-control input-md" typeahead-on-select="notification.attachCertificate($item)" typeahead-wait-ms="500">
|
class="form-control input-md" typeahead-on-select="notification.attachCertificate($item)" typeahead-wait-ms="500">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="certificates.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
<button ng-model="certificates.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
|
||||||
<span class="badge">{{ notification.certificates.total || 0 }}</span>
|
<span class="badge">{{ notification.certificates.total || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
uib-tooltip="Roles control which authorities a user can issue certificates from"
|
uib-tooltip="Roles control which authorities a user can issue certificates from"
|
||||||
tooltip-trigger="focus" tooltip-placement="top">
|
tooltip-trigger="focus" tooltip-placement="top">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button ng-model="roles.show" class="btn btn-md btn-default" btn-checkbox btn-checkbox-true="1"
|
<button ng-model="roles.show" class="btn btn-md btn-default" uib-btn-checkbox btn-checkbox-true="1"
|
||||||
btn-checkbox-false="0">
|
btn-checkbox-false="0">
|
||||||
<span class="badge">{{ user.roles.total || 0 }}</span>
|
<span class="badge">{{ user.roles.total || 0 }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,127 +1,87 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
from lemur.domains.views import * # noqa
|
from lemur.domains.views import * # noqa
|
||||||
|
|
||||||
|
|
||||||
def test_domain_get(client):
|
from .vectors import VALID_ADMIN_HEADER_TOKEN, VALID_USER_HEADER_TOKEN
|
||||||
assert client.get(api.url_for(Domains, domain_id=1)).status_code == 401
|
|
||||||
|
|
||||||
|
|
||||||
def test_domain_post(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.post(api.url_for(Domains, domain_id=1), data={}).status_code == 405
|
(VALID_USER_HEADER_TOKEN, 404),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 404),
|
||||||
|
('', 401)
|
||||||
|
])
|
||||||
|
def test_domain_get(client, token, status):
|
||||||
|
assert client.get(api.url_for(Domains, domain_id=1), headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_domain_put(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.put(api.url_for(Domains, domain_id=1), data={}).status_code == 401
|
(VALID_USER_HEADER_TOKEN, 405),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 405),
|
||||||
|
('', 405)
|
||||||
|
])
|
||||||
|
def test_domain_post_(client, token, status):
|
||||||
|
assert client.post(api.url_for(Domains, domain_id=1), data={}, headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_domain_delete(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.delete(api.url_for(Domains, domain_id=1)).status_code == 405
|
(VALID_USER_HEADER_TOKEN, 400),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 400),
|
||||||
|
('', 401)
|
||||||
|
])
|
||||||
|
def test_domain_put(client, token, status):
|
||||||
|
assert client.put(api.url_for(Domains, domain_id=1), data={}, headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_domain_patch(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.patch(api.url_for(Domains, domain_id=1), data={}).status_code == 405
|
(VALID_USER_HEADER_TOKEN, 405),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 405),
|
||||||
|
('', 405)
|
||||||
|
])
|
||||||
|
def test_domain_delete(client, token, status):
|
||||||
|
assert client.delete(api.url_for(Domains, domain_id=1), headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
VALID_USER_HEADER_TOKEN = {
|
@pytest.mark.parametrize("token,status", [
|
||||||
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'}
|
(VALID_USER_HEADER_TOKEN, 405),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 405),
|
||||||
|
('', 405)
|
||||||
|
])
|
||||||
|
def test_domain_patch(client, token, status):
|
||||||
|
assert client.patch(api.url_for(Domains, domain_id=1), data={}, headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_auth_domain_get(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.get(api.url_for(Domains, domain_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200
|
(VALID_USER_HEADER_TOKEN, 400),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 400),
|
||||||
|
('', 401)
|
||||||
|
])
|
||||||
|
def test_domain_list_post_(client, token, status):
|
||||||
|
assert client.post(api.url_for(DomainsList), data={}, headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_auth_domain_post_(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.post(api.url_for(Domains, domain_id=1), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 405
|
(VALID_USER_HEADER_TOKEN, 200),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 200),
|
||||||
|
('', 401)
|
||||||
|
])
|
||||||
|
def test_domain_list_get(client, token, status):
|
||||||
|
assert client.get(api.url_for(DomainsList), headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_auth_domain_put(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.put(api.url_for(Domains, domain_id=1), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 403
|
(VALID_USER_HEADER_TOKEN, 405),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 405),
|
||||||
|
('', 405)
|
||||||
|
])
|
||||||
|
def test_domain_list_delete(client, token, status):
|
||||||
|
assert client.delete(api.url_for(DomainsList), headers=token).status_code == status
|
||||||
|
|
||||||
|
|
||||||
def test_auth_domain_delete(client):
|
@pytest.mark.parametrize("token,status", [
|
||||||
assert client.delete(api.url_for(Domains, domain_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 405
|
(VALID_USER_HEADER_TOKEN, 405),
|
||||||
|
(VALID_ADMIN_HEADER_TOKEN, 405),
|
||||||
|
('', 405)
|
||||||
def test_auth_domain_patch(client):
|
])
|
||||||
assert client.patch(api.url_for(Domains, domain_id=1), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 405
|
def test_domain_list_patch(client, token, status):
|
||||||
|
assert client.patch(api.url_for(DomainsList), data={}, headers=token).status_code == status
|
||||||
|
|
||||||
VALID_ADMIN_HEADER_TOKEN = {
|
|
||||||
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'}
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_domain_get(client):
|
|
||||||
assert client.get(api.url_for(Domains, domain_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_domain_post(client):
|
|
||||||
assert client.post(api.url_for(Domains, domain_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_domain_put(client):
|
|
||||||
assert client.put(api.url_for(Domains, domain_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_domain_delete(client):
|
|
||||||
assert client.delete(api.url_for(Domains, domain_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_domain_patch(client):
|
|
||||||
assert client.patch(api.url_for(Domains, domain_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_domains_get(client):
|
|
||||||
assert client.get(api.url_for(DomainsList)).status_code == 401
|
|
||||||
|
|
||||||
|
|
||||||
def test_domains_post(client):
|
|
||||||
assert client.post(api.url_for(DomainsList), data={}).status_code == 401
|
|
||||||
|
|
||||||
|
|
||||||
def test_domains_put(client):
|
|
||||||
assert client.put(api.url_for(DomainsList), data={}).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_domains_delete(client):
|
|
||||||
assert client.delete(api.url_for(DomainsList)).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_domains_patch(client):
|
|
||||||
assert client.patch(api.url_for(DomainsList), data={}).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_auth_domains_get(client):
|
|
||||||
assert client.get(api.url_for(DomainsList), headers=VALID_USER_HEADER_TOKEN).status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_domains_get(client):
|
|
||||||
resp = client.get(api.url_for(DomainsList), headers=VALID_ADMIN_HEADER_TOKEN)
|
|
||||||
assert resp.status_code == 200
|
|
||||||
assert resp.json == {'items': [], 'total': 0}
|
|
||||||
|
|
||||||
|
|
||||||
def test_certificate_domains_get(client):
|
|
||||||
assert client.get(api.url_for(CertificateDomains, certificate_id=1)).status_code == 401
|
|
||||||
|
|
||||||
|
|
||||||
def test_certificate_domains_post(client):
|
|
||||||
assert client.post(api.url_for(CertificateDomains, certificate_id=1), data={}).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_certificate_domains_put(client):
|
|
||||||
assert client.put(api.url_for(CertificateDomains, certificate_id=1), data={}).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_certificate_domains_delete(client):
|
|
||||||
assert client.delete(api.url_for(CertificateDomains, certificate_id=1)).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_certificate_domains_patch(client):
|
|
||||||
assert client.patch(api.url_for(CertificateDomains, certificate_id=1), data={}).status_code == 405
|
|
||||||
|
|
||||||
|
|
||||||
def test_auth_certificate_domains_get(client):
|
|
||||||
assert client.get(api.url_for(CertificateDomains, certificate_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_certificate_domains_get(client):
|
|
||||||
assert client.get(api.url_for(CertificateDomains, certificate_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200
|
|
||||||
|
|
Loading…
Reference in New Issue