From 307378c6e15c2aacddbbbda935f698a0aabf247f Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 8 Jun 2022 12:43:45 +0200 Subject: [PATCH] api: filter drafts using SQL to honor limit and offset (#66039) --- wcs/api.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/wcs/api.py b/wcs/api.py index be2a2690e..7de32762d 100644 --- a/wcs/api.py +++ b/wcs/api.py @@ -53,7 +53,7 @@ from .qommon.errors import ( UnknownNameIdAccessForbiddenError, ) from .qommon.form import ComputedExpressionWidget -from .qommon.storage import Contains, Equal, Intersects, Or, StrictNotEqual +from .qommon.storage import Contains, Equal, Intersects, NotContains, Or, StrictNotEqual from .qommon.template import Template, TemplateError @@ -907,7 +907,7 @@ class ApiUserDirectory(Directory): user_info['user_roles'] = [x.get_json_export_dict() for x in user_roles if x] return json.dumps(user_info, cls=misc.JSONEncoder) - def get_user_forms(self, user): + def get_user_forms(self, user, include_drafts=False, include_non_drafts=True): if not (FormDef.exists()): # early return, this avoids running a query against a missing SQL view. return [] @@ -948,6 +948,23 @@ class ApiUserDirectory(Directory): else: return HttpResponseBadRequest('invalid status parameter value') + if include_drafts: + disabled_formdef_ids = [formdef.id for formdef in FormDef.select() if formdef.is_disabled()] + if disabled_formdef_ids: + criterias.append( + Or( + [ + StrictNotEqual('status', 'draft'), + NotContains('formdef_id', disabled_formdef_ids), + ] + ) + ) + else: + criterias.append(StrictNotEqual('status', 'draft')) + + if not include_non_drafts: + criterias.append(Equal('status', 'draft')) + user_forms = sql.AnyFormData.select( criterias, limit=misc.get_int_or_400(get_request().form.get('limit')), @@ -1004,6 +1021,8 @@ class ApiUserDirectory(Directory): return self.forms(include_drafts=True, include_non_drafts=False) def forms(self, include_drafts=False, include_non_drafts=True): + include_drafts = include_drafts or get_query_flag('include-drafts') + get_response().set_content_type('application/json') try: user = self.user or get_user_from_api_query_string() or get_request().user @@ -1018,7 +1037,9 @@ class ApiUserDirectory(Directory): if query_user and query_user.is_api_user and query_user.api_access.restrict_to_anonymised_data: raise AccessForbiddenError('restricted API access') - forms = self.get_user_forms(user) + forms = self.get_user_forms( + user, include_drafts=include_drafts, include_non_drafts=include_non_drafts + ) if self.user: # call to /api/users//forms, this returns the forms of the @@ -1042,7 +1063,6 @@ class ApiUserDirectory(Directory): # ignore confidential forms forms = [x for x in forms if x.readable or not x.formdef.skip_from_360_view] - include_drafts = include_drafts or get_query_flag('include-drafts') result = [] for form in forms: if form.is_draft(): -- 2.35.1