Browse Source

fix #871: invalid captcha failed to interrupt registration process

Rafał Pitoń 8 years ago
parent
commit
6011e6db80

+ 5 - 4
misago/users/api/userendpoints/create.py

@@ -24,14 +24,15 @@ def create_endpoint(request):
 
 
     form = RegisterForm(request.data, request=request)
     form = RegisterForm(request.data, request=request)
 
 
-    if not form.is_valid():
-        return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
-
     try:
     try:
-        captcha.test_request(request)
+        if form.is_valid():
+            captcha.test_request(request)
     except ValidationError as e:
     except ValidationError as e:
         form.add_error('captcha', e)
         form.add_error('captcha', e)
 
 
+    if not form.is_valid():
+        return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
+
     activation_kwargs = {}
     activation_kwargs = {}
     if settings.account_activation == 'user':
     if settings.account_activation == 'user':
         activation_kwargs = {'requires_activation': UserModel.ACTIVATION_USER}
         activation_kwargs = {'requires_activation': UserModel.ACTIVATION_USER}

+ 34 - 0
misago/users/tests/test_user_create_api.py

@@ -1,5 +1,6 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core import mail
 from django.core import mail
+from django.test import override_settings
 from django.urls import reverse
 from django.urls import reverse
 
 
 from misago.conf import settings
 from misago.conf import settings
@@ -235,6 +236,39 @@ class UserCreateTests(UserTestCase):
 
 
         self.assertContains(response, "password is too similar to the username", status_code=400)
         self.assertContains(response, "password is too similar to the username", status_code=400)
 
 
+    @override_settings(captcha_type='qa', qa_question='Test', qa_answers='Lorem\nIpsum')
+    def test_registration_validates_captcha(self):
+        """api validates captcha"""
+        response = self.client.post(
+            self.api_link,
+            data={
+                'username': 'totallyNew',
+                'email': 'loremipsum@dolor.met',
+                'password': 'LoremP4ssword',
+                'captcha': 'dolor'
+            },
+        )
+
+        self.assertEqual(response.status_code, 400)
+        self.assertEqual(
+            response.json(), {
+                'captcha': ['Entered answer is incorrect.'],
+            }
+        )
+
+        # valid captcha
+        response = self.client.post(
+            self.api_link,
+            data={
+                'username': 'totallyNew',
+                'email': 'loremipsum@dolor.met',
+                'password': 'LoremP4ssword',
+                'captcha': 'ipSUM'
+            },
+        )
+
+        self.assertEqual(response.status_code, 200)
+
     def test_registration_calls_validate_new_registration(self):
     def test_registration_calls_validate_new_registration(self):
         """api uses validate_new_registration to validate registrations"""
         """api uses validate_new_registration to validate registrations"""
         response = self.client.post(
         response = self.client.post(