diff --git a/openwisp_ipam/admin.py b/openwisp_ipam/admin.py index 2a7b904..3720a73 100644 --- a/openwisp_ipam/admin.py +++ b/openwisp_ipam/admin.py @@ -10,7 +10,7 @@ from django.db.models import TextField from django.db.models.functions import Cast from django.http import HttpResponse -from django.shortcuts import redirect, render +from django.shortcuts import get_object_or_404, redirect, render from django.urls import path, re_path, reverse from django.utils.translation import gettext_lazy as _ from openwisp_users.multitenancy import MultitenantAdminMixin, MultitenantOrgFilter @@ -145,10 +145,12 @@ def get_urls(self): return custom_urls + urls def export_view(self, request, subnet_id): + # Returns 404 if user is not a manager of the subnet's organization + subnet = get_object_or_404(self.get_queryset(request), pk=subnet_id) response = HttpResponse(content_type="text/csv") response["Content-Disposition"] = 'attachment; filename="ip_address.csv"' writer = csv.writer(response) - Subnet().export_csv(subnet_id, writer) + Subnet().export_csv(subnet.id, writer) return response def import_view(self, request): diff --git a/openwisp_ipam/tests/test_multitenant.py b/openwisp_ipam/tests/test_multitenant.py index bfd8ba9..1c50634 100644 --- a/openwisp_ipam/tests/test_multitenant.py +++ b/openwisp_ipam/tests/test_multitenant.py @@ -96,6 +96,19 @@ def test_import_subnet_permission(self): self.assertContains(response, '
  • You do not have') self.assertEqual(Subnet.objects.count(), 3) + def test_export_subnet_multitenancy(self): + data = self._create_multitenancy_test_env() + self._create_administrator( + organizations=[data["org1"]], + username="org1_administrator", + email="org1administrator@test.com", + ) + self._login(username="org1_administrator", password="tester") + response = self.client.get( + reverse("admin:ipam_export_subnet", args=(data["subnet2"].id,)) + ) + self.assertEqual(response.status_code, 404) + class TestMultitenantApi( TestMultitenantAdminMixin, CreateModelsMixin, PostDataMixin, TestCase