Skip to content

Commit

Permalink
Limit max row count on reports
Browse files Browse the repository at this point in the history
The default is 1000 rows, but can be customized by setting `max_rows` on a `GenericTabularReport` subclass.
  • Loading branch information
millerdev committed Sep 13, 2024
1 parent ddb6327 commit ad83085
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
4 changes: 4 additions & 0 deletions corehq/apps/reports/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
)
from corehq.apps.reports.cache import request_cache
from corehq.apps.reports.datatables import DataTablesHeader
from corehq.apps.reports.exceptions import BadRequestError
from corehq.apps.reports.filters.dates import DatespanFilter
from corehq.apps.reports.tasks import export_all_rows_task
from corehq.apps.reports.util import DatatablesParams
Expand Down Expand Up @@ -830,6 +831,7 @@ class GenericTabularReport(GenericReportView):
statistics_rows = None
force_page_size = False # force page size to be as the default rows
default_rows = 10
max_rows = 1000
start_at_row = 0
show_all_rows = False
fix_left_col = False
Expand Down Expand Up @@ -922,6 +924,8 @@ def pagination(self):
self._pagination = DatatablesParams.from_request_dict(
self.request.POST if self.request.method == 'POST' else self.request.GET
)
if self._pagination.count > self.max_rows:
raise BadRequestError(gettext("Row count is too large"))
return self._pagination

@property
Expand Down
18 changes: 17 additions & 1 deletion corehq/apps/reports/tests/test_generic.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from unittest import expectedFailure

from django.utils.safestring import mark_safe
from django.test import SimpleTestCase
from django.test import RequestFactory, SimpleTestCase

from corehq.apps.reports.exceptions import BadRequestError
from corehq.apps.reports.generic import GenericTabularReport

from ..generic import _sanitize_rows
Expand Down Expand Up @@ -43,6 +44,21 @@ def test_strip_tags_expected_fail(self):
value = GenericTabularReport._strip_tags(value)
self.assertEqual(value, '1 < 8 > 2')

def test_pagination_exceeds_max_rows(self):
class Report(GenericTabularReport):
name = slug = "report"
section_name = "reports"
dispatcher = "fake"

def _update_initial_context(self):
"""override to avoid database hit in test"""

request = RequestFactory().get("/report", {"iDisplayLength": 1001})
report = Report(request)
with self.assertRaises(BadRequestError) as res:
report.pagination
self.assertEqual(str(res.exception), "Row count is too large")


class SanitizeRowTests(SimpleTestCase):
def test_normal_output(self):
Expand Down

0 comments on commit ad83085

Please sign in to comment.