Przeglądaj źródła

fix(api): return 409 (not 500) when POST'ing an unavailable domain

- This happens when the domain is already in the pdns database for
  some reason
- We now return 409 (conflict) in this case instead of 500
- Testcase included
Peter Thomassen 8 lat temu
rodzic
commit
b95cd1e5ea
2 zmienionych plików z 22 dodań i 2 usunięć
  1. 12 0
      api/desecapi/tests/testdomains.py
  2. 10 2
      api/desecapi/views.py

+ 12 - 0
api/desecapi/tests/testdomains.py

@@ -122,6 +122,18 @@ class AuthenticatedDomainTests(APITestCase):
         response = self.client.post(url, data)
         self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
 
+    def testCantPostUnavailableDomain(self):
+        name = utils.generateDomainname()
+
+        httpretty.enable()
+        httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones',
+                               body='{"error": "Domain \'' + name + '.\' already exists"}', status=422)
+
+        url = reverse('domain-list')
+        data = {'name': name}
+        response = self.client.post(url, data)
+        self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
+
     def testCanPostComplicatedDomains(self):
         url = reverse('domain-list')
         data = {'name': 'very.long.domain.name.' + utils.generateDomainname()}

+ 10 - 2
api/desecapi/views.py

@@ -53,7 +53,7 @@ class DomainList(generics.ListCreateAPIView):
 
         queryset = Domain.objects.filter(name=serializer.validated_data['name'])
         if queryset.exists():
-            ex = ValidationError(detail={"detail": "This domain name is already registered.", "code": "domain-taken"})
+            ex = ValidationError(detail={"detail": "This domain name is unavailable.", "code": "domain-unavailable"})
             ex.status_code = status.HTTP_409_CONFLICT
             raise ex
 
@@ -62,7 +62,15 @@ class DomainList(generics.ListCreateAPIView):
             ex.status_code = status.HTTP_403_FORBIDDEN
             raise ex
 
-        obj = serializer.save(owner=self.request.user)
+        try:
+            obj = serializer.save(owner=self.request.user)
+        except Exception as e:
+            if str(e).endswith(' already exists"}'):
+                ex = ValidationError(detail={"detail": "This domain name is unavailable.", "code": "domain-unavailable"})
+                ex.status_code = status.HTTP_409_CONFLICT
+                raise ex
+            else:
+                raise e
 
         def sendDynDnsEmail(domain):
             content_tmpl = get_template('emails/domain-dyndns/content.txt')