From 6726e56b157470dd1c6611226a183d00d852460f Mon Sep 17 00:00:00 2001 From: ozer550 Date: Tue, 22 Oct 2024 17:56:40 +0530 Subject: [PATCH] tests and validation for invalid uuid --- .../kolibri_public/import_metadata_view.py | 9 +++++++++ .../kolibri_public/tests/test_content_app.py | 11 +++++++++++ .../kolibri_public/tests/test_importmetadata_api.py | 11 +++++++++++ contentcuration/kolibri_public/views.py | 12 ++++++++++-- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/contentcuration/kolibri_public/import_metadata_view.py b/contentcuration/kolibri_public/import_metadata_view.py index 534596cbb4..100ac870e3 100644 --- a/contentcuration/kolibri_public/import_metadata_view.py +++ b/contentcuration/kolibri_public/import_metadata_view.py @@ -14,6 +14,7 @@ from kolibri_content.constants.schema_versions import MIN_CONTENT_SCHEMA_VERSION # Use kolibri_content from kolibri_public import models # Use kolibri_public models from kolibri_public.views import metadata_cache +from rest_framework import status from rest_framework.generics import get_object_or_404 from rest_framework.permissions import AllowAny from rest_framework.response import Response @@ -69,6 +70,14 @@ def retrieve(self, request, pk=None): # noqa: C901 :return: an object with keys for each content metadata table and a schema_version key """ + try: + UUID(pk) + except ValueError: + return Response( + {"error": "Invalid UUID format."}, + status=status.HTTP_400_BAD_REQUEST + ) + content_schema = request.query_params.get( "schema_version", self.default_content_schema ) diff --git a/contentcuration/kolibri_public/tests/test_content_app.py b/contentcuration/kolibri_public/tests/test_content_app.py index 50c4a6a35b..0b6800e0e5 100644 --- a/contentcuration/kolibri_public/tests/test_content_app.py +++ b/contentcuration/kolibri_public/tests/test_content_app.py @@ -236,6 +236,17 @@ def _recurse_and_assert(self, data, nodes, recursion_depth=0): ) return recursion_depth if not recursion_depths else max(recursion_depths) + def test_contentnode_tree_invalid_uuid(self): + invalid_uuid = "8f0a5b9d89795" + + response = self._get( + reverse("publiccontentnode_tree-detail", kwargs={"pk": invalid_uuid}) + ) + + self.assertEqual(response.status_code, 400) + + self.assertEqual(response.data["error"], "Invalid UUID format.") + def test_contentnode_tree(self): response = self._get( reverse("publiccontentnode_tree-detail", kwargs={"pk": self.root.id}) diff --git a/contentcuration/kolibri_public/tests/test_importmetadata_api.py b/contentcuration/kolibri_public/tests/test_importmetadata_api.py index b9184f6de1..484fa6c382 100644 --- a/contentcuration/kolibri_public/tests/test_importmetadata_api.py +++ b/contentcuration/kolibri_public/tests/test_importmetadata_api.py @@ -85,6 +85,17 @@ def test_import_metadata_through_tags(self): def test_import_metadata_tags(self): self._assert_data(public.ContentTag, content.ContentTag, self.tags) + def test_import_metadata_invalid_uuid(self): + invalid_uuid = "8f0a5b9d89795" + + response = self.client.get( + reverse("publicimportmetadata-detail", kwargs={"pk": invalid_uuid}) + ) + + self.assertEqual(response.status_code, 400) + + self.assertEqual(response.data["error"], "Invalid UUID format.") + def test_schema_version_too_low(self): response = self.client.get( reverse("publicimportmetadata-detail", kwargs={"pk": self.node.id}) diff --git a/contentcuration/kolibri_public/views.py b/contentcuration/kolibri_public/views.py index 8c66b1993b..faa5588d88 100644 --- a/contentcuration/kolibri_public/views.py +++ b/contentcuration/kolibri_public/views.py @@ -10,6 +10,7 @@ import re from collections import OrderedDict from functools import reduce +from uuid import UUID from django.core.exceptions import ValidationError from django.db.models import Exists @@ -35,6 +36,7 @@ from kolibri_public.search import get_available_metadata_labels from kolibri_public.stopwords import stopwords_set from le_utils.constants import content_kinds +from rest_framework import status from rest_framework.permissions import AllowAny from rest_framework.response import Response @@ -45,7 +47,6 @@ from contentcuration.viewsets.base import BaseValuesViewset from contentcuration.viewsets.base import ReadOnlyValuesViewset - logger = logging.getLogger(__name__) @@ -697,8 +698,15 @@ def retrieve(self, request, pk=None): :return: an object representing the parent with a pagination object as "children" """ - queryset = self.get_tree_queryset(request, pk) + try: + UUID(pk) + except ValueError: + return Response( + {"error": "Invalid UUID format."}, + status=status.HTTP_400_BAD_REQUEST + ) + queryset = self.get_tree_queryset(request, pk) # We explicitly order by lft here, so that the nodes are in tree traversal order, so we can iterate over them and build # out our nested representation, being sure that any ancestors have already been processed. nodes = self.serialize(queryset.order_by("lft"))