Browse Source

#893: fixed te misago.markup api to detect malformed request data

Rafał Pitoń 7 years ago
parent
commit
fb4e0fe31a

+ 15 - 14
misago/markup/api.py

@@ -2,24 +2,25 @@ from rest_framework import status
 from rest_framework.decorators import api_view
 from rest_framework.response import Response
 
-from django.core.exceptions import ValidationError
-from django.utils import six
-
-from misago.threads.validators import validate_post_length
-
 from . import common_flavour, finalise_markup
+from .serializers import MarkupSerializer
 
 
 @api_view(['POST'])
 def parse_markup(request):
-    post = six.text_type(request.data.get('post', '')).strip()
-
-    try:
-        validate_post_length(post)
-    except ValidationError as e:
-        return Response({'detail': e.args[0]}, status=status.HTTP_400_BAD_REQUEST)
-
-    parsed = common_flavour(request, request.user, post, force_shva=True)['parsed_text']
-    finalised = finalise_markup(parsed)
+    serializer = MarkupSerializer(data=request.data)
+    if not serializer.is_valid():
+        return Response(
+            serializer.errors['non_field_errors'][0],
+            status=status.HTTP_400_BAD_REQUEST,
+        )
+
+    parsing_result = common_flavour(
+        request,
+        request.user,
+        serializer.data['post'],
+        force_shva=True,
+    )
+    finalised = finalise_markup(parsing_result['parsed_text'])
 
     return Response({'parsed': finalised})

+ 11 - 0
misago/markup/serializers.py

@@ -0,0 +1,11 @@
+from rest_framework import serializers
+
+from misago.threads.validators import validate_post_length
+
+
+class MarkupSerializer(serializers.Serializer):
+    post = serializers.CharField(required=False)
+
+    def validate(self, data):
+        validate_post_length(data.get('post', ''))
+        return data

+ 14 - 0
misago/markup/tests/test_api.py

@@ -24,6 +24,20 @@ class ParseMarkupApiTests(AuthenticatedUserTestCase):
         response = self.client.post(self.api_link)
         self.assertContains(response, "You have to enter a message.", status_code=400)
 
+    def test_invalid_data(self):
+        """api handles post that is invalid type"""
+        response = self.client.post(self.api_link, '[]', content_type="application/json")
+        self.assertContains(response, "Invalid data. Expected a dictionary, but got list.", status_code=400)
+
+        response = self.client.post(self.api_link, '123', content_type="application/json")
+        self.assertContains(response, "Invalid data. Expected a dictionary, but got int.", status_code=400)
+
+        response = self.client.post(self.api_link, '"string"', content_type="application/json")
+        self.assertContains(response, "Invalid data. Expected a dictionary, but got unicode.", status_code=400)
+
+        response = self.client.post(self.api_link, 'malformed', content_type="application/json")
+        self.assertContains(response, "JSON parse error - No JSON object could be decoded", status_code=400)
+
     def test_empty_post(self):
         """api handles empty post"""
         response = self.client.post(self.api_link, {'post': ''})

+ 1 - 5
misago/threads/tests/test_post_mentions.py

@@ -41,11 +41,7 @@ class PostMentionsTests(AuthenticatedUserTestCase):
 
         override_acl(self.user, new_acl)
 
-    def put(
-            self,
-            url,
-            data=None,
-    ):
+    def put(self, url, data=None):
         content = encode_multipart(BOUNDARY, data or {})
         return self.client.put(url, content, content_type=MULTIPART_CONTENT)