Skip to content

Commit 48e1263

Browse files
committed
[fix] Multi-tenancy for reversion endpoints
1 parent 64c4300 commit 48e1263

2 files changed

Lines changed: 29 additions & 11 deletions

File tree

openwisp_controller/config/api/views.py

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
get_object_or_404,
1818
)
1919
from rest_framework.response import Response
20-
from reversion.models import Version
20+
from reversion.models import Revision, Version
2121
from swapper import load_model
2222

2323
from openwisp_users.api.permissions import DjangoModelPermissions
@@ -309,10 +309,18 @@ class BaseReversionView:
309309
def get_queryset(self):
310310
model = self.kwargs.get("model").lower()
311311
content_type = get_object_or_404(ContentType, model=model)
312-
return super().get_queryset().filter(content_type=content_type)
313-
314-
315-
class ReversionListView(BaseReversionView, ProtectedAPIMixin, ListAPIView):
312+
qs = super().get_queryset().filter(content_type=content_type)
313+
user = self.request.user
314+
if user.is_superuser:
315+
return qs
316+
model_class = content_type.model_class()
317+
allowed_object_ids = model_class.objects.filter(
318+
organization__in=user.organizations_managed
319+
).values_list("pk", flat=True)
320+
return qs.filter(object_id__in=allowed_object_ids)
321+
322+
323+
class ReversionListView(BaseReversionView, ListAPIView):
316324
serializer_class = ReversionSerializer
317325
queryset = Version.objects.select_related("revision").order_by(
318326
"-revision__date_created"
@@ -322,27 +330,36 @@ class ReversionListView(BaseReversionView, ProtectedAPIMixin, ListAPIView):
322330
pagination_class = ListViewPagination
323331

324332

325-
class ReversionDetailView(BaseReversionView, ProtectedAPIMixin, RetrieveAPIView):
333+
class ReversionDetailView(BaseReversionView, RetrieveAPIView):
326334
serializer_class = ReversionSerializer
327335
queryset = Version.objects.select_related("revision")
328336

329337

330-
class ReversionRestoreView(BaseReversionView, ProtectedAPIMixin, GenericAPIView):
338+
class ReversionRestoreView(BaseReversionView, GenericAPIView):
331339
serializer_class = serializers.Serializer
332340
queryset = Version.objects.select_related("revision").order_by(
333341
"-revision__date_created"
334342
)
335343

336344
def post(self, request, *args, **kwargs):
337345
qs = self.get_queryset()
338-
version = get_object_or_404(qs, revision_id=kwargs["pk"])
339-
revision = version.revision
346+
revision = get_object_or_404(Revision, pk=kwargs["pk"])
347+
if not qs.filter(revision=revision).exists():
348+
raise Http404
349+
comment = f"Restored to previous revision: {revision.id}"
340350
with transaction.atomic():
341351
with reversion.create_revision():
342352
revision.revert()
343353
reversion.set_user(request.user)
344-
reversion.set_comment(f"Restored to previous revision: {revision.id}")
345-
versions = qs.filter(revision=revision)
354+
reversion.set_comment(comment)
355+
restored_revision = get_object_or_404(
356+
Revision.objects.order_by(
357+
"-date_created"
358+
),
359+
user=request.user,
360+
comment=comment,
361+
)
362+
versions = qs.filter(revision=restored_revision)
346363
serializer = ReversionSerializer(
347364
versions, many=True, context=self.get_serializer_context()
348365
)

openwisp_controller/config/tests/test_api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,7 @@ def test_config_modified_signal(self):
17791779
self.assertEqual(template2.default_values["ifname"], "eth3")
17801780
mocked_signal.assert_called_once()
17811781

1782+
# Todo: create sperate test for each endpoint
17821783
def test_reversion_list_and_restore_api(self):
17831784
org = self._get_org()
17841785
model_slug = "device"

0 commit comments

Comments
 (0)