Просмотр исходного кода

Fixes #7101: Enforce MAX_PAGE_SIZE for table and REST API pagination

jeremystretch 4 лет назад
Родитель
Сommit
1c09ffdd1f

+ 1 - 0
docs/release-notes/version-3.0.md

@@ -13,6 +13,7 @@
 * [#7084](https://github.com/netbox-community/netbox/issues/7084) - Fix KeyError exception when editing access VLAN on an interface
 * [#7084](https://github.com/netbox-community/netbox/issues/7084) - Fix KeyError exception when editing access VLAN on an interface
 * [#7089](https://github.com/netbox-community/netbox/issues/7089) - Fix ContentTypeFilterSet not filtering on q filter
 * [#7089](https://github.com/netbox-community/netbox/issues/7089) - Fix ContentTypeFilterSet not filtering on q filter
 * [#7096](https://github.com/netbox-community/netbox/issues/7096) - Home links should honor `BASE_PATH` configuration
 * [#7096](https://github.com/netbox-community/netbox/issues/7096) - Home links should honor `BASE_PATH` configuration
+* [#7101](https://github.com/netbox-community/netbox/issues/7101) - Enforce `MAX_PAGE_SIZE` for table and REST API pagination
 
 
 ---
 ---
 
 

+ 6 - 16
netbox/netbox/api/pagination.py

@@ -34,23 +34,13 @@ class OptionalLimitOffsetPagination(LimitOffsetPagination):
             return list(queryset[self.offset:])
             return list(queryset[self.offset:])
 
 
     def get_limit(self, request):
     def get_limit(self, request):
+        limit = super().get_limit(request)
 
 
-        if self.limit_query_param:
-            try:
-                limit = int(request.query_params[self.limit_query_param])
-                if limit < 0:
-                    raise ValueError()
-                # Enforce maximum page size, if defined
-                if settings.MAX_PAGE_SIZE:
-                    if limit == 0:
-                        return settings.MAX_PAGE_SIZE
-                    else:
-                        return min(limit, settings.MAX_PAGE_SIZE)
-                return limit
-            except (KeyError, ValueError):
-                pass
-
-        return self.default_limit
+        # Enforce maximum page size
+        if settings.MAX_PAGE_SIZE:
+            limit = min(limit, settings.MAX_PAGE_SIZE)
+
+        return limit
 
 
     def get_next_link(self):
     def get_next_link(self):
 
 

+ 4 - 0
netbox/netbox/settings.py

@@ -560,6 +560,10 @@ RQ_QUEUES = {
 #
 #
 
 
 # Pagination
 # Pagination
+if MAX_PAGE_SIZE and PAGINATE_COUNT > MAX_PAGE_SIZE:
+    raise ImproperlyConfigured(
+        f"PAGINATE_COUNT ({PAGINATE_COUNT}) must be less than or equal to MAX_PAGE_SIZE ({MAX_PAGE_SIZE}), if set."
+    )
 PER_PAGE_DEFAULTS = [
 PER_PAGE_DEFAULTS = [
     25, 50, 100, 250, 500, 1000
     25, 50, 100, 250, 500, 1000
 ]
 ]

+ 8 - 4
netbox/utilities/paginator.py

@@ -49,21 +49,25 @@ class EnhancedPage(Page):
 
 
 def get_paginate_count(request):
 def get_paginate_count(request):
     """
     """
-    Determine the length of a page, using the following in order:
+    Determine the desired length of a page, using the following in order:
 
 
         1. per_page URL query parameter
         1. per_page URL query parameter
         2. Saved user preference
         2. Saved user preference
         3. PAGINATE_COUNT global setting.
         3. PAGINATE_COUNT global setting.
+
+    Return the lesser of the calculated value and MAX_PAGE_SIZE.
     """
     """
     if 'per_page' in request.GET:
     if 'per_page' in request.GET:
         try:
         try:
             per_page = int(request.GET.get('per_page'))
             per_page = int(request.GET.get('per_page'))
             if request.user.is_authenticated:
             if request.user.is_authenticated:
                 request.user.config.set('pagination.per_page', per_page, commit=True)
                 request.user.config.set('pagination.per_page', per_page, commit=True)
-            return per_page
+            return min(per_page, settings.MAX_PAGE_SIZE)
         except ValueError:
         except ValueError:
             pass
             pass
 
 
     if request.user.is_authenticated:
     if request.user.is_authenticated:
-        return request.user.config.get('pagination.per_page', settings.PAGINATE_COUNT)
-    return settings.PAGINATE_COUNT
+        per_page = request.user.config.get('pagination.per_page', settings.PAGINATE_COUNT)
+        return min(per_page, settings.MAX_PAGE_SIZE)
+
+    return min(settings.PAGINATE_COUNT, settings.MAX_PAGE_SIZE)