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.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 import validators
@ -66,7 +66,7 @@ class AuthorityOutputSchema(LemurOutputSchema):
owner = fields.Email()
not_before = fields.DateTime()
not_after = fields.DateTime()
plugin_name = fields.String()
plugin = fields.Nested(PluginOutputSchema)
body = fields.String()
chain = fields.String()
active = fields.Boolean()

View File

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

View File

@ -239,9 +239,6 @@ def update_list(model, model_attr, item_model, items):
"""
ids = []
for i in items:
ids.append(i['id'])
for i in getattr(model, model_attr):
if i.id not in ids:
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.description = description
notification.active = active
notification = database.update_list(notification, 'certificates', Certificate, certificates)
notification.certificates = certificates
return database.update(notification)

View File

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

View File

@ -7,36 +7,25 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
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.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
mod = Blueprint('plugins', __name__)
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):
""" Defines the 'plugins' endpoint """
def __init__(self):
self.reqparse = reqparse.RequestParser()
super(PluginsList, self).__init__()
@marshal_items(FIELDS)
@validate_schema(None, plugins_output_schema)
def get(self):
"""
.. http:get:: /plugins
@ -94,7 +83,7 @@ class Plugins(AuthenticatedResource):
def __init__(self):
super(Plugins, self).__init__()
@marshal_items(FIELDS)
@validate_schema(None, plugin_output_schema)
def get(self, name):
"""
.. http:get:: /plugins/<name>

View File

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

View File

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

View File

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

View File

@ -35,9 +35,9 @@
<div class="col-sm-10">
<div class="input-group">
<input type="text" ng-model="authority.selectedRole" placeholder="Role Name"
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"
tooltip="Roles control which authorities a user can issue certificates from"
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-wait-ms="500"
uib-tooltip="Roles control which authorities a user can issue certificates from"
tooltip-trigger="focus" tooltip-placement="top">
<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">

View File

@ -8,7 +8,7 @@
</div>
<div class="col-sm-5">
<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">
<button ng-click="authority.attachSubAltName()" class="btn btn-info">Add</button>
</span>
@ -132,12 +132,12 @@
</label>
<div class="col-sm-10">
<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
</label>
</div>
<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
</label>
</div>
@ -149,7 +149,7 @@
</label>
<div class="col-sm-10">
<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
</label>
</div>
@ -161,7 +161,7 @@
</label>
<div class="col-sm-10">
<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
</label>
</div>
@ -180,14 +180,14 @@
Custom
</label>
<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 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 class="col-sm-4">
<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">
<button ng-click="authority.attachCustom()" class="btn btn-info">Add</button>
</span>

View File

@ -5,9 +5,9 @@
<div class="col-sm-10">
<div class="input-group">
<input type="text" ng-model="authority.selectedRole" placeholder="Role Name"
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"
tooltip="These are the User roles you wish to associated with your authority"
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-wait-ms="500"
uib-tooltip="These are the User roles you wish to associated with your authority"
tooltip-trigger="focus" tooltip-placement="top">
<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">

View File

@ -37,7 +37,7 @@
<td data-title="''">
<div class="btn-group pull-right">
<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
</button>
</div>

View File

@ -10,7 +10,7 @@
</div>
<div class="col-sm-5">
<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">
<button ng-click="certificate.attachSubAltName()" class="btn btn-info">Add</button>
</span>
@ -139,12 +139,12 @@
</label>
<div class="col-sm-10">
<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
</label>
</div>
<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
</label>
</div>
@ -156,7 +156,7 @@
</label>
<div class="col-sm-10">
<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
</label>
</div>
@ -168,7 +168,7 @@
</label>
<div class="col-sm-10">
<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
</label>
</div>
@ -187,14 +187,14 @@
Custom
</label>
<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 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 class="col-sm-4">
<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">
<button ng-click="certificate.attachCustom()" class="btn btn-info">Add</button>
</span>

View File

@ -67,13 +67,13 @@
</li>
<li class="list-group-item">
<strong>Not Before</strong>
<span class="pull-right" tooltip="{{ certificate.notBefore }}">
<span class="pull-right" uib-tooltip="{{ certificate.notBefore }}">
{{ momentService.createMoment(certificate.notBefore) }}
</span>
</li>
<li class="list-group-item">
<strong>Not After</strong>
<span class="pull-right" tooltip="{{ certificate.notAfter }}">
<span class="pull-right" uib-tooltip="{{ certificate.notAfter }}">
{{ momentService.createMoment(certificate.notAfter) }}
</span>
</li>
@ -97,7 +97,7 @@
<span class="pull-right">{{ certificate.serial }}</span>
</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">
<strong>Validity</strong>
<span class="pull-right">
@ -152,7 +152,7 @@
<tab-heading>
Chain
<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>
</tab-heading>
<pre style="width: 100%">{{ certificate.chain }}</pre>
@ -161,7 +161,7 @@
<tab-heading>
Public Certificate
<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>
</tab-heading>
<pre style="width: 100%">{{ certificate.body }}</pre>
@ -170,7 +170,7 @@
<tab-heading>
Private Key
<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>
</tab-heading>
<pre style="width: 100%">{{ certificate.privateKey }}</pre>

View File

@ -30,10 +30,10 @@
</td>
<td data-title="''">
<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
</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
</button>
</div>

View File

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

View File

@ -53,8 +53,8 @@
<div class="col-sm-10">
<div class="input-group">
<input type="text" ng-model="notification.selectedCertificate" placeholder="Certificate Name"
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">
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">
<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">
<span class="badge">{{ notification.certificates.total || 0 }}</span>

View File

@ -35,10 +35,10 @@
</td>
<td data-title="''">
<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
</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
</button>
</div>

View File

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

View File

@ -30,10 +30,10 @@
</td>
<td data-title="''">
<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
</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
</button>
</div>

View File

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

View File

@ -56,10 +56,10 @@
<div class="col-sm-10">
<div class="input-group">
<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"
class="form-control input-md" typeahead-on-select="user.attachRole($item)" typeahead-min-wait="50"
tooltip="Roles control which authorities a user can issue certificates from"
class="form-control input-md" typeahead-on-select="user.attachRole($item)" typeahead-wait-ms="500"
uib-tooltip="Roles control which authorities a user can issue certificates from"
tooltip-trigger="focus" tooltip-placement="top">
<span class="input-group-btn">
<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 data-title="''">
<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
</button>
</div>

View File

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

View File

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