From cd49e3cd4c69ad89152e9a63766676de6f0f8711 Mon Sep 17 00:00:00 2001 From: Ceesjan Luiten Date: Thu, 30 May 2024 15:40:53 +0200 Subject: [PATCH] Restore compatibility with iptools.IpRangeList --- debug_toolbar/middleware.py | 15 ++++++++++++--- tests/test_integration.py | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 0513e2379..65b5282c5 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -20,8 +20,14 @@ def show_toolbar(request): """ Default function to determine whether to show the toolbar on a given page. """ - internal_ips = list(settings.INTERNAL_IPS) + if not settings.DEBUG: + return False + # Test: settings + if request.META.get("REMOTE_ADDR") in settings.INTERNAL_IPS: + return True + + # Test: Docker try: # This is a hack for docker installations. It attempts to look # up the IP address of the docker host. @@ -31,11 +37,14 @@ def show_toolbar(request): ".".join(socket.gethostbyname("host.docker.internal").rsplit(".")[:-1]) + ".1" ) - internal_ips.append(docker_ip) + if request.META.get("REMOTE_ADDR") == docker_ip: + return True except socket.gaierror: # It's fine if the lookup errored since they may not be using docker pass - return settings.DEBUG and request.META.get("REMOTE_ADDR") in internal_ips + + # No test passed + return False @lru_cache(maxsize=None) diff --git a/tests/test_integration.py b/tests/test_integration.py index 465804651..71525affe 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -75,6 +75,28 @@ def test_show_toolbar_docker(self, mocked_gethostbyname): self.assertTrue(show_toolbar(self.request)) mocked_gethostbyname.assert_called_once_with("host.docker.internal") + def test_not_iterating_over_INTERNAL_IPS(self): + """Verify that the middleware does not iterate over INTERNAL_IPS in some way. + + Some people use iptools.IpRangeList for their INTERNAL_IPS. This is a class + that can quickly answer the question if the setting contain a certain IP address, + but iterating over this object will drain all performance / blow up. + """ + + class FailOnIteration: + def __iter__(self): + raise RuntimeError( + "The testcase failed: the code should not have iterated over INTERNAL_IPS" + ) + + def __contains__(self, x): + return True + + with self.settings(INTERNAL_IPS=FailOnIteration()): + response = self.client.get("/regular/basic/") + self.assertEqual(response.status_code, 200) + self.assertContains(response, "djDebug") # toolbar + def test_should_render_panels_RENDER_PANELS(self): """ The toolbar should force rendering panels on each request