Skip to content

Commit

Permalink
Fix validation of querystring-search input (#1653)
Browse files Browse the repository at this point in the history
* Fix validation of querystring-search input

* Handle empty query

* split tests

* changelog
  • Loading branch information
davisagli committed Jun 6, 2023
1 parent bd9eb3d commit a93d70a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 8 deletions.
1 change: 1 addition & 0 deletions news/1653.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Validate input to the `@querystring-search` service. Input which can't be processed now results in a 400 response instead of 500. @davisagli
37 changes: 29 additions & 8 deletions src/plone/restapi/services/querystringsearch/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
from pkg_resources import parse_version
from plone.restapi.bbb import IPloneSiteRoot
from plone.restapi.deserializer import json_body
from plone.restapi.exceptions import DeserializationError
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.services import Service
from urllib import parse
from zExceptions import BadRequest
from zope.component import getMultiAdapter


Expand All @@ -23,17 +25,30 @@ def __init__(self, context, request):
self.request = request

def __call__(self):
data = json_body(self.request)
try:
data = json_body(self.request)
except DeserializationError as err:
raise BadRequest(str(err))

query = data.get("query", None)
b_start = int(data.get("b_start", 0))
b_size = int(data.get("b_size", 25))
try:
b_start = int(data.get("b_start", 0))
except ValueError:
raise BadRequest("Invalid b_start")
try:
b_size = int(data.get("b_size", 25))
except ValueError:
raise BadRequest("Invalid b_size")
sort_on = data.get("sort_on", None)
sort_order = data.get("sort_order", None)
limit = int(data.get("limit", 1000))
fullobjects = data.get("fullobjects", False)
try:
limit = int(data.get("limit", 1000))
except ValueError:
raise BadRequest("Invalid limit")
fullobjects = bool(data.get("fullobjects", False))

if query is None:
raise Exception("No query supplied")
if not query:
raise BadRequest("No query supplied")

if sort_order:
sort_order = "descending" if sort_order == "descending" else "ascending"
Expand All @@ -59,7 +74,13 @@ def __call__(self):
dict(custom_query={"UID": {"not": self.context.UID()}})
)

results = querybuilder(**querybuilder_parameters)
try:
results = querybuilder(**querybuilder_parameters)
except KeyError:
# This can happen if the query has an invalid operation,
# but plone.app.querystring doesn't raise an exception
# with specific info.
raise BadRequest("Invalid query.")

results = getMultiAdapter((results, self.request), ISerializeToJson)(
fullobjects=fullobjects
Expand Down
42 changes: 42 additions & 0 deletions src/plone/restapi/tests/test_services_querystringsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,45 @@ def test_querystringsearch_sort(self):
response.json()["items"][-1]["@id"],
f"{self.portal.absolute_url()}/testdocument9",
)

def test_querystringsearch__bad_json(self):
response = self.api_session.get("/@querystring-search?query={")
self.assertEqual(response.status_code, 400)

def test_querystringsearch__empty_query(self):
response = self.api_session.post(
"/@querystring-search",
json={"query": []},
)
self.assertEqual(response.status_code, 400)

def test_querystringsearch__bad_b_size(self):
response = self.api_session.post(
"/@querystring-search",
json={
"query": [
{
"i": "portal_type",
"o": "plone.app.querystring.operation.selection.is",
"v": ["Document"],
}
],
"b_size": "x",
},
)
self.assertEqual(response.status_code, 400)

def test_querystringsearch__bad_operation(self):
response = self.api_session.post(
"/@querystring-search",
json={
"query": [
{
"i": "portal_type",
"o": "BOGUS",
"v": ["Document"],
}
],
},
)
self.assertEqual(response.status_code, 400)

0 comments on commit a93d70a

Please sign in to comment.