adding a new API for faster certificate lookup.
The new API api/1/certificates/valid returns only non-expired (not_after >= today) certs which have auto-rotate enabled: cn is a required parameter: http://localhost:8000/api/1/certificates/valid?filter=cn;example.com cn can also be a database string wildcard ('%'): http://localhost:8000/api/1/certificates/valid?filter=cn;% owner is the additional parameter, and must be the email address of the owner: http://localhost:8000/api/1/certificates/valid?filter=cn;example.com&owner=hossein@example.com given owner and a database string wildcard ('%') one can retrieve all certs for that owner, which are still valid, and have auto-rotate enabled: http://localhost:8000/api/1/certificates/valid?filter=cn;%&owner=hossein@example.com
This commit is contained in:
parent
0f2773c986
commit
f452a7ce68
|
@ -401,6 +401,30 @@ def query_name(certificate_name, args):
|
|||
return result
|
||||
|
||||
|
||||
def query_common_name(common_name, args):
|
||||
"""
|
||||
Helper function that queries for not expired certificates by common name and owner which have auto-rotate enabled
|
||||
|
||||
:param common_name:
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
owner = args.pop('owner')
|
||||
if not owner:
|
||||
owner = '%'
|
||||
|
||||
# only not expired certificates
|
||||
current_time = arrow.utcnow()
|
||||
|
||||
result = Certificate.query.filter(Certificate.cn.ilike(common_name)) \
|
||||
.filter(Certificate.owner.ilike(owner))\
|
||||
.filter(Certificate.not_after >= current_time.format('YYYY-MM-DD')) \
|
||||
.filter(Certificate.rotation.is_(True))\
|
||||
.all()
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def create_csr(**csr_config):
|
||||
"""
|
||||
Given a list of domains create the appropriate csr
|
||||
|
|
|
@ -37,6 +37,102 @@ mod = Blueprint('certificates', __name__)
|
|||
api = Api(mod)
|
||||
|
||||
|
||||
class CertificatesListValid(AuthenticatedResource):
|
||||
""" Defines the 'certificates/valid' endpoint """
|
||||
|
||||
def __init__(self):
|
||||
self.reqparse = reqparse.RequestParser()
|
||||
super(CertificatesListValid, self).__init__()
|
||||
|
||||
@validate_schema(None, certificates_output_schema)
|
||||
def get(self):
|
||||
"""
|
||||
.. http:get:: /certificates/valid/<query>
|
||||
|
||||
The current list of not-expired certificates for a given common name, and owner
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
GET /certificates/valid?filter=cn;*.test.example.net&owner=joe@example.com
|
||||
HTTP/1.1
|
||||
Host: example.com
|
||||
Accept: application/json, text/javascript
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: text/javascript
|
||||
|
||||
{
|
||||
"items": [{
|
||||
"status": null,
|
||||
"cn": "*.test.example.net",
|
||||
"chain": "",
|
||||
"csr": "-----BEGIN CERTIFICATE REQUEST-----"
|
||||
"authority": {
|
||||
"active": true,
|
||||
"owner": "secure@example.com",
|
||||
"id": 1,
|
||||
"description": "verisign test authority",
|
||||
"name": "verisign"
|
||||
},
|
||||
"owner": "joe@example.com",
|
||||
"serial": "82311058732025924142789179368889309156",
|
||||
"id": 2288,
|
||||
"issuer": "SymantecCorporation",
|
||||
"dateCreated": "2016-06-03T06:09:42.133769+00:00",
|
||||
"notBefore": "2016-06-03T00:00:00+00:00",
|
||||
"notAfter": "2018-01-12T23:59:59+00:00",
|
||||
"destinations": [],
|
||||
"bits": 2048,
|
||||
"body": "-----BEGIN CERTIFICATE-----...",
|
||||
"description": null,
|
||||
"deleted": null,
|
||||
"notifications": [{
|
||||
"id": 1
|
||||
}],
|
||||
"signingAlgorithm": "sha256",
|
||||
"user": {
|
||||
"username": "jane",
|
||||
"active": true,
|
||||
"email": "jane@example.com",
|
||||
"id": 2
|
||||
},
|
||||
"active": true,
|
||||
"domains": [{
|
||||
"sensitive": false,
|
||||
"id": 1090,
|
||||
"name": "*.test.example.net"
|
||||
}],
|
||||
"replaces": [],
|
||||
"replaced": [],
|
||||
"name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
|
||||
"roles": [{
|
||||
"id": 464,
|
||||
"description": "This is a google group based role created by Lemur",
|
||||
"name": "joe@example.com"
|
||||
}],
|
||||
"san": null
|
||||
}],
|
||||
"total": 1
|
||||
}
|
||||
|
||||
:reqheader Authorization: OAuth token to authenticate
|
||||
:statuscode 200: no error
|
||||
:statuscode 403: unauthenticated
|
||||
|
||||
"""
|
||||
parser = paginated_parser.copy()
|
||||
args = parser.parse_args()
|
||||
args['user'] = g.user
|
||||
common_name = args['filter'].split(';')[1]
|
||||
return service.query_common_name(common_name, args)
|
||||
|
||||
|
||||
class CertificatesNameQuery(AuthenticatedResource):
|
||||
""" Defines the 'certificates/name' endpoint """
|
||||
|
||||
|
@ -1190,6 +1286,7 @@ class CertificateRevoke(AuthenticatedResource):
|
|||
api.add_resource(CertificateRevoke, '/certificates/<int:certificate_id>/revoke', endpoint='revokeCertificate')
|
||||
api.add_resource(CertificatesNameQuery, '/certificates/name/<string:certificate_name>', endpoint='certificatesNameQuery')
|
||||
api.add_resource(CertificatesList, '/certificates', endpoint='certificates')
|
||||
api.add_resource(CertificatesListValid, '/certificates/valid', endpoint='certificatesListValid')
|
||||
api.add_resource(Certificates, '/certificates/<int:certificate_id>', endpoint='certificate')
|
||||
api.add_resource(CertificatesStats, '/certificates/stats', endpoint='certificateStats')
|
||||
api.add_resource(CertificatesUpload, '/certificates/upload', endpoint='certificateUpload')
|
||||
|
|
|
@ -30,6 +30,7 @@ paginated_parser.add_argument('page', type=int, default=1, location='args')
|
|||
paginated_parser.add_argument('sortDir', type=str, dest='sort_dir', location='args')
|
||||
paginated_parser.add_argument('sortBy', type=str, dest='sort_by', location='args')
|
||||
paginated_parser.add_argument('filter', type=str, location='args')
|
||||
paginated_parser.add_argument('owner', type=str, location='args')
|
||||
|
||||
|
||||
def get_psuedo_random_string():
|
||||
|
|
Loading…
Reference in New Issue