Merge pull request #3347 from charhate/pagination

Paginate valid certificate fetch API
This commit is contained in:
charhate 2021-01-06 14:54:48 -08:00 committed by GitHub
commit 4c8edbb43e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 9 deletions

View File

@ -563,10 +563,15 @@ def query_common_name(common_name, args):
:return:
"""
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
current_time = arrow.utcnow()
query = Certificate.query.filter(Certificate.not_after >= current_time.format("YYYY-MM-DD"))\
query = query.filter(Certificate.not_after >= current_time.format("YYYY-MM-DD"))\
.filter(not_(Certificate.revoked))\
.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
query = query.filter(Certificate.cn.ilike(common_name))
if paginate:
return database.paginate(query, page, count)
return query.all()

View File

@ -51,17 +51,20 @@ class CertificatesListValid(AuthenticatedResource):
"""
.. 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**:
.. 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
Host: example.com
Accept: application/json, text/javascript
**Example response**:
**Example response (with single cert to be concise)**:
.. sourcecode:: http
@ -128,10 +131,15 @@ class CertificatesListValid(AuthenticatedResource):
:statuscode 403: unauthenticated
"""
parser = paginated_parser.copy()
args = parser.parse_args()
# using non-paginated parser to ensure backward compatibility
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
common_name = args["filter"].split(";")[1]
common_name = args.pop("filter").split(";")[1]
return service.query_common_name(common_name, args)

View File

@ -225,7 +225,9 @@ def paginate(query, page, count):
:param page:
: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):