Fixes various issues. (#316)

This commit is contained in:
kevgliss 2016-05-13 14:35:38 -07:00
parent a0c8765588
commit 58e8fe0bd0
26 changed files with 72 additions and 86 deletions

View File

@ -11,7 +11,7 @@ from marshmallow import fields, validates_schema
from marshmallow import validate from marshmallow import validate
from marshmallow.exceptions import ValidationError from marshmallow.exceptions import ValidationError
from lemur.schemas import PluginInputSchema, ExtensionSchema, AssociatedAuthoritySchema, AssociatedRoleSchema from lemur.schemas import PluginInputSchema, PluginOutputSchema, ExtensionSchema, AssociatedAuthoritySchema, AssociatedRoleSchema
from lemur.common.schema import LemurInputSchema, LemurOutputSchema from lemur.common.schema import LemurInputSchema, LemurOutputSchema
from lemur.common import validators from lemur.common import validators
@ -66,7 +66,7 @@ class AuthorityOutputSchema(LemurOutputSchema):
owner = fields.Email() owner = fields.Email()
not_before = fields.DateTime() not_before = fields.DateTime()
not_after = fields.DateTime() not_after = fields.DateTime()
plugin_name = fields.String() plugin = fields.Nested(PluginOutputSchema)
body = fields.String() body = fields.String()
chain = fields.String() chain = fields.String()
active = fields.Boolean() active = fields.Boolean()

View File

@ -47,7 +47,7 @@ def create(kwargs):
:return: :return:
""" """
issuer = kwargs['plugin'] issuer = kwargs['plugin']['plugin_object']
kwargs['creator'] = g.current_user.email kwargs['creator'] = g.current_user.email
cert_body, intermediate, issuer_roles = issuer.create_authority(kwargs) cert_body, intermediate, issuer_roles = issuer.create_authority(kwargs)
@ -77,7 +77,7 @@ def create(kwargs):
role = role_service.create( role = role_service.create(
r['name'], r['name'],
password=r['password'], password=r['password'],
description="{0} auto generated role".format(kwargs['plugin'].title), description="{0} auto generated role".format(issuer.title),
username=r['username']) username=r['username'])
# the user creating the authority should be able to administer it # the user creating the authority should be able to administer it
@ -89,7 +89,7 @@ def create(kwargs):
authority = Authority( authority = Authority(
kwargs.get('name'), kwargs.get('name'),
kwargs['owner'], kwargs['owner'],
kwargs['plugin'].slug, issuer.slug,
cert_body, cert_body,
description=kwargs['description'], description=kwargs['description'],
chain=intermediate, chain=intermediate,

View File

@ -239,9 +239,6 @@ def update_list(model, model_attr, item_model, items):
""" """
ids = [] ids = []
for i in items:
ids.append(i['id'])
for i in getattr(model, model_attr): for i in getattr(model, model_attr):
if i.id not in ids: if i.id not in ids:
getattr(model, model_attr).remove(i) getattr(model, model_attr).remove(i)

View File

@ -273,7 +273,7 @@ def update(notification_id, label, options, description, active, certificates):
notification.options = options notification.options = options
notification.description = description notification.description = description
notification.active = active notification.active = active
notification = database.update_list(notification, 'certificates', Certificate, certificates) notification.certificates = certificates
return database.update(notification) return database.update(notification)

View File

@ -335,7 +335,7 @@ class Notifications(AuthenticatedResource):
return service.update( return service.update(
notification_id, notification_id,
data['label'], data['label'],
data['notificationOptions'], data['plugin']['plugin_options'],
data['description'], data['description'],
data['active'], data['active'],
data['certificates'] data['certificates']
@ -352,7 +352,7 @@ class CertificateNotifications(AuthenticatedResource):
super(CertificateNotifications, self).__init__() super(CertificateNotifications, self).__init__()
@validate_schema(None, notifications_output_schema) @validate_schema(None, notifications_output_schema)
def get(self, certificate_id, data=None): def get(self, certificate_id):
""" """
.. http:get:: /certificates/1/notifications .. http:get:: /certificates/1/notifications
@ -426,8 +426,7 @@ class CertificateNotifications(AuthenticatedResource):
:reqheader Authorization: OAuth token to authenticate :reqheader Authorization: OAuth token to authenticate
:statuscode 200: no error :statuscode 200: no error
""" """
data['certificate_id'] = certificate_id return service.render({'certificate_id': certificate_id})
return service.render(data)
api.add_resource(NotificationsList, '/notifications', endpoint='notifications') api.add_resource(NotificationsList, '/notifications', endpoint='notifications')

View File

@ -7,36 +7,25 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
from flask import Blueprint from flask import Blueprint
from flask.ext.restful import Api, reqparse, fields from flask.ext.restful import Api, reqparse
from lemur.auth.service import AuthenticatedResource from lemur.auth.service import AuthenticatedResource
from lemur.common.utils import marshal_items
from lemur.schemas import plugins_output_schema, plugin_output_schema
from lemur.common.schema import validate_schema
from lemur.plugins.base import plugins from lemur.plugins.base import plugins
mod = Blueprint('plugins', __name__) mod = Blueprint('plugins', __name__)
api = Api(mod) api = Api(mod)
FIELDS = {
'title': fields.String,
'pluginOptions': fields.Raw(attribute='options'),
'description': fields.String,
'version': fields.String,
'author': fields.String,
'authorUrl': fields.String,
'type': fields.String,
'slug': fields.String,
}
class PluginsList(AuthenticatedResource): class PluginsList(AuthenticatedResource):
""" Defines the 'plugins' endpoint """ """ Defines the 'plugins' endpoint """
def __init__(self): def __init__(self):
self.reqparse = reqparse.RequestParser() self.reqparse = reqparse.RequestParser()
super(PluginsList, self).__init__() super(PluginsList, self).__init__()
@marshal_items(FIELDS) @validate_schema(None, plugins_output_schema)
def get(self): def get(self):
""" """
.. http:get:: /plugins .. http:get:: /plugins
@ -94,7 +83,7 @@ class Plugins(AuthenticatedResource):
def __init__(self): def __init__(self):
super(Plugins, self).__init__() super(Plugins, self).__init__()
@marshal_items(FIELDS) @validate_schema(None, plugin_output_schema)
def get(self, name): def get(self, name):
""" """
.. http:get:: /plugins/<name> .. http:get:: /plugins/<name>

View File

@ -6,6 +6,8 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
from marshmallow import fields from marshmallow import fields
from lemur.users.schemas import UserOutputSchema
from lemur.authorities.schemas import AuthorityOutputSchema
from lemur.common.schema import LemurInputSchema, LemurOutputSchema from lemur.common.schema import LemurInputSchema, LemurOutputSchema
from lemur.schemas import AssociatedUserSchema, AssociatedAuthoritySchema from lemur.schemas import AssociatedUserSchema, AssociatedAuthoritySchema
@ -23,12 +25,9 @@ class RoleInputSchema(LemurInputSchema):
class RoleOutputSchema(LemurOutputSchema): class RoleOutputSchema(LemurOutputSchema):
id = fields.Integer() id = fields.Integer()
name = fields.String() name = fields.String()
username = fields.String()
password = fields.String()
description = fields.String() description = fields.String()
authorities = fields.Nested(AssociatedAuthoritySchema, many=True) authorities = fields.Nested(AuthorityOutputSchema, many=True)
users = fields.Nested(AssociatedUserSchema, many=True) users = fields.Nested(UserOutputSchema, many=True)
users = fields.Nested(AssociatedUserSchema, many=True)
role_input_schema = RoleInputSchema() role_input_schema = RoleInputSchema()

View File

@ -30,7 +30,7 @@ class RolesList(AuthenticatedResource):
self.reqparse = reqparse.RequestParser() self.reqparse = reqparse.RequestParser()
super(RolesList, self).__init__() super(RolesList, self).__init__()
@validate_schema(None, role_output_schema) @validate_schema(None, roles_output_schema)
def get(self): def get(self):
""" """
.. http:get:: /roles .. http:get:: /roles

View File

@ -118,6 +118,10 @@ class PluginOutputSchema(LemurOutputSchema):
title = fields.String() title = fields.String()
plugins_output_schema = PluginOutputSchema(many=True)
plugin_output_schema = PluginOutputSchema
class BaseExtensionSchema(LemurSchema): class BaseExtensionSchema(LemurSchema):
@pre_load(pass_many=True) @pre_load(pass_many=True)
def preprocess(self, data, many): def preprocess(self, data, many):

View File

@ -35,9 +35,9 @@
<div class="col-sm-10"> <div class="col-sm-10">
<div class="input-group"> <div class="input-group">
<input type="text" ng-model="authority.selectedRole" placeholder="Role Name" <input type="text" ng-model="authority.selectedRole" placeholder="Role Name"
typeahead="role.name for role in roleService.findRoleByName($viewValue)" typeahead-loading="loadingRoles" uib-typeahead="role.name for role in roleService.findRoleByName($viewValue)" typeahead-loading="loadingRoles"
class="form-control input-md" typeahead-on-select="authority.attachRole($item)" typeahead-min-wait="50" class="form-control input-md" typeahead-on-select="authority.attachRole($item)" typeahead-wait-ms="500"
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" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">

View File

@ -8,7 +8,7 @@
</div> </div>
<div class="col-sm-5"> <div class="col-sm-5">
<div class="input-group"> <div class="input-group">
<input tooltip-trigger="focus" tooltip-placement="top" tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="authority.subAltValue" placeholder="Value" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="authority.subAltValue" placeholder="Value" class="form-control" required/>
<span class="input-group-btn"> <span class="input-group-btn">
<button ng-click="authority.attachSubAltName()" class="btn btn-info">Add</button> <button ng-click="authority.attachSubAltName()" class="btn btn-info">Add</button>
</span> </span>
@ -132,12 +132,12 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Put Issuer's keyIdentifier in this extension" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Put Issuer's keyIdentifier in this extension" >
<input type="checkbox" ng-model="authority.extensions.authorityKeyIdentifier.useKeyIdentifier">Key Identifier <input type="checkbox" ng-model="authority.extensions.authorityKeyIdentifier.useKeyIdentifier">Key Identifier
</label> </label>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Put Issuer's Name and Serial number" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Put Issuer's Name and Serial number" >
<input type="checkbox" ng-model="authority.extensions.authorityKeyIdentifier.useAuthorityCert">Authority Certificate <input type="checkbox" ng-model="authority.extensions.authorityKeyIdentifier.useAuthorityCert">Authority Certificate
</label> </label>
</div> </div>
@ -149,7 +149,7 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Ask CA to include/not include AIA extension" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Ask CA to include/not include AIA extension" >
<input type="checkbox" ng-model="authority.extensions.authorityInfoAccess.includeAIA">Include AIA <input type="checkbox" ng-model="authority.extensions.authorityInfoAccess.includeAIA">Include AIA
</label> </label>
</div> </div>
@ -161,7 +161,7 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Ask CA to include/not include Subject Key Identifier" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Ask CA to include/not include Subject Key Identifier" >
<input type="checkbox" ng-model="authority.extensions.subjectKeyIdentifier.includeSKI">Include SKI <input type="checkbox" ng-model="authority.extensions.subjectKeyIdentifier.includeSKI">Include SKI
</label> </label>
</div> </div>
@ -180,14 +180,14 @@
Custom Custom
</label> </label>
<div class="col-sm-2"> <div class="col-sm-2">
<input tooltip-trigger="focus" tooltip-placement="top" tooltip="OID for the custom extension e.g. 1.12.123.12.10" class="form-control" name="oid" ng-model="authority.customOid" placeholder="Oid" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="OID for the custom extension e.g. 1.12.123.12.10" class="form-control" name="oid" ng-model="authority.customOid" placeholder="Oid" class="form-control" required/>
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<select tooltip-trigger="focus" tooltip-placement="top" tooltip="Encoding for value" class="form-control col-sm-2" ng-model="authority.customEncoding" ng-options="item for item in ['b64asn1', 'string', 'ia5string']"></select> <select tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="Encoding for value" class="form-control col-sm-2" ng-model="authority.customEncoding" ng-options="item for item in ['b64asn1', 'string', 'ia5string']"></select>
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<div class="input-group"> <div class="input-group">
<input tooltip-trigger="focus" tooltip-placement="top" tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="authority.customValue" placeholder="Value" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="authority.customValue" placeholder="Value" class="form-control" required/>
<span class="input-group-btn"> <span class="input-group-btn">
<button ng-click="authority.attachCustom()" class="btn btn-info">Add</button> <button ng-click="authority.attachCustom()" class="btn btn-info">Add</button>
</span> </span>

View File

@ -5,9 +5,9 @@
<div class="col-sm-10"> <div class="col-sm-10">
<div class="input-group"> <div class="input-group">
<input type="text" ng-model="authority.selectedRole" placeholder="Role Name" <input type="text" ng-model="authority.selectedRole" placeholder="Role Name"
typeahead="role.name for role in roleService.findRoleByName($viewValue)" typeahead-loading="loadingAccounts" uib-typeahead="role.name for role in roleService.findRoleByName($viewValue)" typeahead-loading="loadingAccounts"
class="form-control input-md" typeahead-on-select="authority.attachRole($item)" typeahead-min-wait="50" class="form-control input-md" typeahead-on-select="authority.attachRole($item)" typeahead-wait-ms="500"
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" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">

View File

@ -37,7 +37,7 @@
<td data-title="''"> <td data-title="''">
<div class="btn-group pull-right"> <div class="btn-group pull-right">
<a class="btn btn-sm btn-default" ui-sref="authority({name: authority.name})">Permalink</a> <a class="btn btn-sm btn-default" ui-sref="authority({name: authority.name})">Permalink</a>
<button tooltip="Edit Authority" ng-click="edit(authority.id)" class="btn btn-sm btn-info"> <button uib-tooltip="Edit Authority" ng-click="edit(authority.id)" class="btn btn-sm btn-info">
Edit Edit
</button> </button>
</div> </div>

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="col-sm-5"> <div class="col-sm-5">
<div class="input-group"> <div class="input-group">
<input tooltip-trigger="focus" tooltip-placement="top" tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="certificate.subAltValue" placeholder="Value" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="certificate.subAltValue" placeholder="Value" class="form-control" required/>
<span class="input-group-btn"> <span class="input-group-btn">
<button ng-click="certificate.attachSubAltName()" class="btn btn-info">Add</button> <button ng-click="certificate.attachSubAltName()" class="btn btn-info">Add</button>
</span> </span>
@ -139,12 +139,12 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Put Issuer's keyIdentifier in this extension" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Put Issuer's keyIdentifier in this extension" >
<input type="checkbox" ng-model="certificate.extensions.authorityKeyIdentifier.useKeyIdentifier">Key Identifier <input type="checkbox" ng-model="certificate.extensions.authorityKeyIdentifier.useKeyIdentifier">Key Identifier
</label> </label>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Put Issuer's Name and Serial number" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Put Issuer's Name and Serial number" >
<input type="checkbox" ng-model="certificate.extensions.authorityIdentifier.useAuthorityCert">Authority Certificate <input type="checkbox" ng-model="certificate.extensions.authorityIdentifier.useAuthorityCert">Authority Certificate
</label> </label>
</div> </div>
@ -156,7 +156,7 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Ask CA to include/not include AIA extension" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Ask CA to include/not include AIA extension" >
<input type="checkbox" ng-model="certificate.extensions.certificateInfoAccess.includeAIA">Include AIA <input type="checkbox" ng-model="certificate.extensions.certificateInfoAccess.includeAIA">Include AIA
</label> </label>
</div> </div>
@ -168,7 +168,7 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="checkbox"> <div class="checkbox">
<label tooltip-trigger="mouseenter" tooltip-placement="top" tooltip="Ask CA to include/not include Subject Key Identifier" > <label tooltip-trigger="mouseenter" tooltip-placement="top" uib-tooltip="Ask CA to include/not include Subject Key Identifier" >
<input type="checkbox" ng-model="certificate.extensions.subjectKeyIdentifier.includeSKI">Include SKI <input type="checkbox" ng-model="certificate.extensions.subjectKeyIdentifier.includeSKI">Include SKI
</label> </label>
</div> </div>
@ -187,14 +187,14 @@
Custom Custom
</label> </label>
<div class="col-sm-2"> <div class="col-sm-2">
<input tooltip-trigger="focus" tooltip-placement="top" tooltip="OID for the custom extension e.g. 1.12.123.12.10" class="form-control" name="oid" ng-model="certificate.customOid" placeholder="Oid" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="OID for the custom extension e.g. 1.12.123.12.10" class="form-control" name="oid" ng-model="certificate.customOid" placeholder="Oid" class="form-control" required/>
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<select tooltip-trigger="focus" tooltip-placement="top" tooltip="Encoding for value" class="form-control col-sm-2" ng-model="certificate.customEncoding" ng-options="item for item in ['b64asn1', 'string', 'ia5string']"></select> <select tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="Encoding for value" class="form-control col-sm-2" ng-model="certificate.customEncoding" ng-options="item for item in ['b64asn1', 'string', 'ia5string']"></select>
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<div class="input-group"> <div class="input-group">
<input tooltip-trigger="focus" tooltip-placement="top" tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="certificate.customValue" placeholder="Value" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="certificate.customValue" placeholder="Value" class="form-control" required/>
<span class="input-group-btn"> <span class="input-group-btn">
<button ng-click="certificate.attachCustom()" class="btn btn-info">Add</button> <button ng-click="certificate.attachCustom()" class="btn btn-info">Add</button>
</span> </span>

View File

@ -67,13 +67,13 @@
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<strong>Not Before</strong> <strong>Not Before</strong>
<span class="pull-right" tooltip="{{ certificate.notBefore }}"> <span class="pull-right" uib-tooltip="{{ certificate.notBefore }}">
{{ momentService.createMoment(certificate.notBefore) }} {{ momentService.createMoment(certificate.notBefore) }}
</span> </span>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<strong>Not After</strong> <strong>Not After</strong>
<span class="pull-right" tooltip="{{ certificate.notAfter }}"> <span class="pull-right" uib-tooltip="{{ certificate.notAfter }}">
{{ momentService.createMoment(certificate.notAfter) }} {{ momentService.createMoment(certificate.notAfter) }}
</span> </span>
</li> </li>
@ -97,7 +97,7 @@
<span class="pull-right">{{ certificate.serial }}</span> <span class="pull-right">{{ certificate.serial }}</span>
</li> </li>
<li <li
tooltip="Lemur will attempt to check a certificates validity, this is used to track whether a certificate as been revoked" uib-tooltip="Lemur will attempt to check a certificates validity, this is used to track whether a certificate as been revoked"
class="list-group-item"> class="list-group-item">
<strong>Validity</strong> <strong>Validity</strong>
<span class="pull-right"> <span class="pull-right">
@ -152,7 +152,7 @@
<tab-heading> <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"
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> </tab-heading>
<pre style="width: 100%">{{ certificate.chain }}</pre> <pre style="width: 100%">{{ certificate.chain }}</pre>
@ -161,7 +161,7 @@
<tab-heading> <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"
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> </tab-heading>
<pre style="width: 100%">{{ certificate.body }}</pre> <pre style="width: 100%">{{ certificate.body }}</pre>
@ -170,7 +170,7 @@
<tab-heading> <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"
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> </tab-heading>
<pre style="width: 100%">{{ certificate.privateKey }}</pre> <pre style="width: 100%">{{ certificate.privateKey }}</pre>

View File

@ -30,10 +30,10 @@
</td> </td>
<td data-title="''"> <td data-title="''">
<div class="btn-group-vertical pull-right"> <div class="btn-group-vertical pull-right">
<button tooltip="Edit Destination" ng-click="edit(destination.id)" class="btn btn-sm btn-info"> <button uib-tooltip="Edit Destination" ng-click="edit(destination.id)" class="btn btn-sm btn-info">
Edit Edit
</button> </button>
<button tooltip="Delete Destination" ng-click="remove(destination)" type="button" class="btn btn-sm btn-danger pull-left"> <button uib-tooltip="Delete Destination" ng-click="remove(destination)" type="button" class="btn btn-sm btn-danger pull-left">
Remove Remove
</button> </button>
</div> </div>

View File

@ -67,7 +67,7 @@ angular.module('lemur')
toaster.pop({ toaster.pop({
type: 'success', type: 'success',
title: notification.label, title: notification.label,
body: 'Successfully Created!' body: 'Successfully Updated!'
}); });
$uibModalInstance.close(); $uibModalInstance.close();
}, function (response) { }, function (response) {

View File

@ -53,8 +53,8 @@
<div class="col-sm-10"> <div class="col-sm-10">
<div class="input-group"> <div class="input-group">
<input type="text" ng-model="notification.selectedCertificate" placeholder="Certificate Name" <input type="text" ng-model="notification.selectedCertificate" placeholder="Certificate Name"
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-min-wait="50"> 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" 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>

View File

@ -35,10 +35,10 @@
</td> </td>
<td data-title="''"> <td data-title="''">
<div class="btn-group-vertical pull-right"> <div class="btn-group-vertical pull-right">
<button tooltip="Edit Notification" ng-click="edit(notification.id)" class="btn btn-sm btn-info"> <button uib-tooltip="Edit Notification" ng-click="edit(notification.id)" class="btn btn-sm btn-info">
Edit Edit
</button> </button>
<button tooltip="Delete Notification" ng-click="remove(notification)" type="button" class="btn btn-sm btn-danger pull-left"> <button uib-tooltip="Delete Notification" ng-click="remove(notification)" type="button" class="btn btn-sm btn-danger pull-left">
Remove Remove
</button> </button>
</div> </div>

View File

@ -58,9 +58,9 @@
<div class="form-group"> <div class="form-group">
<label class="control-label col-sm-2">User(s)</label> <label class="control-label col-sm-2">User(s)</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input tooltip="You can attach any user to this role, once attached they will have access as defined by this role" <input uib-tooltip="You can attach any user to this role, once attached they will have access as defined by this role"
typeahead="user.username for user in userService.findUserByName($viewValue)" typeahead-loading="loadingUsers" uib-typeahead="user.username for user in userService.findUserByName($viewValue)" typeahead-loading="loadingUsers"
typeahead-min-wait="100" typeahead-on-select="role.addUser($item)" typeahead-wait-ms="500" typeahead-on-select="role.addUser($item)"
type="text" name="user" ng-model="role.selectedUser" placeholder="Username..." class="form-control"/> type="text" name="user" ng-model="role.selectedUser" placeholder="Username..." class="form-control"/>
<table ng-show="role.users" class="table"> <table ng-show="role.users" class="table">
<tr ng-repeat="user in role.users track by $index"> <tr ng-repeat="user in role.users track by $index">

View File

@ -30,10 +30,10 @@
</td> </td>
<td data-title="''"> <td data-title="''">
<div class="btn-group-vertical pull-right"> <div class="btn-group-vertical pull-right">
<button tooltip="Edit Source" ng-click="edit(source.id)" class="btn btn-sm btn-info"> <button uib-tooltip="Edit Source" ng-click="edit(source.id)" class="btn btn-sm btn-info">
Edit Edit
</button> </button>
<button tooltip="Delete Source" ng-click="remove(source)" type="button" class="btn btn-sm btn-danger pull-left"> <button uib-tooltip="Delete Source" ng-click="remove(source)" type="button" class="btn btn-sm btn-danger pull-left">
Remove Remove
</button> </button>
</div> </div>

View File

@ -4,7 +4,6 @@ angular.module('lemur')
.controller('UsersEditController', function ($scope, $uibModalInstance, UserApi, UserService, RoleService, toaster, editId) { .controller('UsersEditController', function ($scope, $uibModalInstance, UserApi, UserService, RoleService, toaster, editId) {
UserApi.get(editId).then(function (user) { UserApi.get(editId).then(function (user) {
UserService.getRoles(user);
$scope.user = user; $scope.user = user;
}); });

View File

@ -56,10 +56,10 @@
<div class="col-sm-10"> <div class="col-sm-10">
<div class="input-group"> <div class="input-group">
<input type="text" ng-model="user.selectedRole" placeholder="Role Name" <input type="text" ng-model="user.selectedRole" placeholder="Role Name"
typeahead="role.name for role in roleService.findRoleByName($viewValue)" uib-typeahead="role.name for role in roleService.findRoleByName($viewValue)"
typeahead-loading="loadingRoles" typeahead-loading="loadingRoles"
class="form-control input-md" typeahead-on-select="user.attachRole($item)" typeahead-min-wait="50" class="form-control input-md" typeahead-on-select="user.attachRole($item)" typeahead-wait-ms="500"
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" btn-checkbox btn-checkbox-true="1"

View File

@ -29,7 +29,7 @@
</td> </td>
<td data-title="''"> <td data-title="''">
<div class="btn-group-vertical pull-right"> <div class="btn-group-vertical pull-right">
<button tooltip="Edit User" ng-click="edit(user.id)" class="btn btn-sm btn-info"> <button uib-tooltip="Edit User" ng-click="edit(user.id)" class="btn btn-sm btn-info">
Edit Edit
</button> </button>
</div> </div>

View File

@ -15,16 +15,15 @@ class UserInputSchema(LemurInputSchema):
email = fields.Email(required=True) email = fields.Email(required=True)
password = fields.String(required=True) # TODO add complexity requirements password = fields.String(required=True) # TODO add complexity requirements
active = fields.Boolean() active = fields.Boolean()
roles = fields.Nested(AssociatedRoleSchema, many=True) roles = fields.Nested(AssociatedRoleSchema, many=True, missing=[])
certificates = fields.Nested(AssociatedCertificateSchema, many=True) certificates = fields.Nested(AssociatedCertificateSchema, many=True, missing=[])
authorities = fields.Nested(AssociatedAuthoritySchema, many=True) authorities = fields.Nested(AssociatedAuthoritySchema, many=True, missing=[])
class UserOutputSchema(LemurOutputSchema): class UserOutputSchema(LemurOutputSchema):
id = fields.Integer() id = fields.Integer()
username = fields.String() username = fields.String()
email = fields.Email() email = fields.Email()
password = fields.String()
active = fields.Boolean() active = fields.Boolean()
roles = fields.Nested(AssociatedRoleSchema, many=True) roles = fields.Nested(AssociatedRoleSchema, many=True)
certificates = fields.Nested(AssociatedCertificateSchema, many=True) certificates = fields.Nested(AssociatedCertificateSchema, many=True)

View File

@ -229,7 +229,7 @@ class CertificateUsers(AuthenticatedResource):
self.reqparse = reqparse.RequestParser() self.reqparse = reqparse.RequestParser()
super(CertificateUsers, self).__init__() super(CertificateUsers, self).__init__()
@validate_schema(None, users_output_schema) @validate_schema(None, user_output_schema)
def get(self, certificate_id): def get(self, certificate_id):
""" """
.. http:get:: /certificates/1/creator .. http:get:: /certificates/1/creator