Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Commit

Permalink
Merge pull request #95 from peterbe/bug-1165412-disallow-massive-page…
Browse files Browse the repository at this point in the history
…sizes-on-cases

fixes bug 1165412 - Disallow massive pagesizes on cases
  • Loading branch information
camd committed May 15, 2015
2 parents 845d1bb + 60bec08 commit 038861b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
11 changes: 11 additions & 0 deletions moztrap/view/lists/pagination.py
Expand Up @@ -4,6 +4,7 @@
"""
import math
from django.db.utils import DatabaseError
from django.core.exceptions import SuspiciousOperation
from ..utils.querystring import update_querystring


Expand All @@ -25,6 +26,16 @@ def from_request(request):
request.GET.get("pagesize", default_pagesize), default_pagesize)
pagenumber = positive_integer(
request.GET.get("pagenumber", 1), 1)

# To avoid causing page rendering with massive querysets,
# as soon as possible we disallow setting a pagesize that is too
# big as it would cause too expensive rendering.
if pagesize not in PAGESIZES:
# If you raise a SuspiciousOperation in runtime, Django
# will automatically respond with a 400 Bad Request to the
# whole request.
raise SuspiciousOperation("Unrecognized pagination size")

return pagesize, pagenumber


Expand Down
24 changes: 21 additions & 3 deletions tests/view/lists/templatetags/test_pagination.py
Expand Up @@ -5,6 +5,7 @@
from mock import Mock

from django import template
from django.core.exceptions import SuspiciousOperation

from tests import case

Expand All @@ -21,16 +22,33 @@ def test_paginate(self):
"{% for obj in pager.objects %}{{ obj }} {% endfor %}")

request = Mock()
request.GET = {"pagesize": 3, "pagenumber": 2}
request.GET = {"pagesize": 20, "pagenumber": 2}

for i in range(1, 7):
for i in range(1, 25):
self.F.TagFactory.create(name=str(i))
qs = Tag.objects.all()

output = tpl.render(
template.Context({"request": request, "queryset": qs}))

self.assertEqual(output, "4 5 6 ")
self.assertEqual(output, "21 22 23 24 ")

def test_paginate_outsize_known_size(self):
from moztrap.model.tags.models import Tag

tpl = template.Template(
"{% load pagination %}{% paginate queryset as pager %}"
"{% for obj in pager.objects %}{{ obj }} {% endfor %}")

request = Mock()
request.GET = {"pagesize": 99, "pagenumber": 1}

qs = Tag.objects.all()
self.assertRaises(
SuspiciousOperation,
tpl.render,
template.Context({"request": request, "queryset": qs})
)


class FilterTest(case.TestCase):
Expand Down
15 changes: 14 additions & 1 deletion tests/view/lists/test_pagination.py
Expand Up @@ -4,6 +4,8 @@
"""
from mock import Mock

from django.core.exceptions import SuspiciousOperation

from tests import case

from tests.utils import Url
Expand Down Expand Up @@ -43,8 +45,19 @@ def test_invalid(self):

def test_negative(self):
"""Out-of-bounds numbers are constrained to bounds."""
self._check({"pagesize": 15, "pagenumber": -2}, (15, 1))
self._check({"pagesize": 20, "pagenumber": -2}, (20, 1))


def test_valid_number_but_not_allowed(self):
"""Value that is a sane number but not in the
PAGESIZES list"""
request = Mock()
request.GET = {"pagesize": 99, "pagenumber": 1}
self.assertRaises(
SuspiciousOperation,
self.func,
request
)


class TestPagesizeUrl(case.TestCase):
Expand Down

0 comments on commit 038861b

Please sign in to comment.