Paginate valid certificate fetch API

This commit is contained in:
sayali 2021-01-06 11:28:18 -08:00
parent 396e3afdfa
commit ba050028ca
3 changed files with 27 additions and 9 deletions

View File

@ -563,10 +563,15 @@ def query_common_name(common_name, args):
:return: :return:
""" """
owner = args.pop("owner") owner = args.pop("owner")
page = args.pop("page")
count = args.pop("count")
paginate = page and count
query = database.session_query(Certificate) if paginate else Certificate.query
# only not expired certificates # only not expired certificates
current_time = arrow.utcnow() current_time = arrow.utcnow()
query = query.filter(Certificate.not_after >= current_time.format("YYYY-MM-DD"))\
query = Certificate.query.filter(Certificate.not_after >= current_time.format("YYYY-MM-DD"))\
.filter(not_(Certificate.revoked))\ .filter(not_(Certificate.revoked))\
.filter(not_(Certificate.replaced.any())) # ignore rotated certificates to avoid duplicates .filter(not_(Certificate.replaced.any())) # ignore rotated certificates to avoid duplicates
@ -577,6 +582,9 @@ def query_common_name(common_name, args):
# if common_name is a wildcard ('%'), no need to include it in the query # if common_name is a wildcard ('%'), no need to include it in the query
query = query.filter(Certificate.cn.ilike(common_name)) query = query.filter(Certificate.cn.ilike(common_name))
if paginate:
return database.paginate(query, page, count)
return query.all() return query.all()

View File

@ -51,17 +51,20 @@ class CertificatesListValid(AuthenticatedResource):
""" """
.. http:get:: /certificates/valid/<query> .. http:get:: /certificates/valid/<query>
The current list of not-expired certificates for a given common name, and owner The current list of not-expired certificates for a given common name, and owner. The API offers
optional pagination. One can send page number(>=1) and desired count per page. The returned data
contains total number of certificates which can help in determining the last page. Pagination
will not be offered if page or count info is not sent or if it is zero.
**Example request**: **Example request**:
.. sourcecode:: http .. sourcecode:: http
GET /certificates/valid?filter=cn;*.test.example.net&owner=joe@example.com GET /certificates/valid?filter=cn;*.test.example.net&owner=joe@example.com&page=1&count=20
HTTP/1.1 HTTP/1.1
Host: example.com Host: example.com
Accept: application/json, text/javascript Accept: application/json, text/javascript
**Example response**: **Example response (with single cert to be concise)**:
.. sourcecode:: http .. sourcecode:: http
@ -128,10 +131,15 @@ class CertificatesListValid(AuthenticatedResource):
:statuscode 403: unauthenticated :statuscode 403: unauthenticated
""" """
parser = paginated_parser.copy() # using non-paginated parser to ensure backward compatibility
args = parser.parse_args() self.reqparse.add_argument("filter", type=str, location="args")
self.reqparse.add_argument("owner", type=str, location="args")
self.reqparse.add_argument("count", type=int, location="args")
self.reqparse.add_argument("page", type=int, location="args")
args = self.reqparse.parse_args()
args["user"] = g.user args["user"] = g.user
common_name = args["filter"].split(";")[1] common_name = args.pop("filter").split(";")[1]
return service.query_common_name(common_name, args) return service.query_common_name(common_name, args)

View File

@ -225,7 +225,9 @@ def paginate(query, page, count):
:param page: :param page:
:param count: :param count:
""" """
return query.paginate(page, count) total = get_count(query)
items = query.paginate(page, count).items
return dict(items=items, total=total, current=len(items))
def update_list(model, model_attr, item_model, items): def update_list(model, model_attr, item_model, items):