testdomains.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. from django.core.urlresolvers import reverse
  2. from rest_framework import status
  3. from rest_framework.test import APITestCase
  4. from .utils import utils
  5. from desecapi.models import Domain
  6. from django.core import mail
  7. import httpretty
  8. from django.conf import settings
  9. import json
  10. class UnauthenticatedDomainTests(APITestCase):
  11. def testExpectUnauthorizedOnGet(self):
  12. url = reverse('domain-list')
  13. response = self.client.get(url, format='json')
  14. self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
  15. def testExpectUnauthorizedOnPost(self):
  16. url = reverse('domain-list')
  17. response = self.client.post(url, format='json')
  18. self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
  19. def testExpectUnauthorizedOnPut(self):
  20. url = reverse('domain-detail', args=(1,))
  21. response = self.client.put(url, format='json')
  22. self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
  23. def testExpectUnauthorizedOnDelete(self):
  24. url = reverse('domain-detail', args=(1,))
  25. response = self.client.delete(url, format='json')
  26. self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
  27. class AuthenticatedDomainTests(APITestCase):
  28. def setUp(self):
  29. if not hasattr(self, 'owner'):
  30. self.owner = utils.createUser()
  31. self.ownedDomains = [utils.createDomain(self.owner), utils.createDomain(self.owner)]
  32. self.otherDomains = [utils.createDomain(), utils.createDomain()]
  33. self.token = utils.createToken(user=self.owner)
  34. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
  35. def tearDown(self):
  36. httpretty.reset()
  37. httpretty.disable()
  38. def testExpectOnlyOwnedDomains(self):
  39. url = reverse('domain-list')
  40. response = self.client.get(url, format='json')
  41. self.assertEqual(response.status_code, status.HTTP_200_OK)
  42. self.assertEqual(len(response.data), 2)
  43. self.assertEqual(response.data[0]['name'], self.ownedDomains[0].name)
  44. self.assertEqual(response.data[1]['name'], self.ownedDomains[1].name)
  45. def testCanDeleteOwnedDomain(self):
  46. httpretty.enable()
  47. httpretty.register_uri(httpretty.DELETE, settings.NSLORD_PDNS_API + '/zones/' + self.ownedDomains[1].name + '.')
  48. httpretty.register_uri(httpretty.DELETE, settings.NSMASTER_PDNS_API + '/zones/' + self.ownedDomains[1].name+ '.')
  49. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  50. response = self.client.delete(url)
  51. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
  52. self.assertEqual(httpretty.last_request().method, 'DELETE')
  53. self.assertEqual(httpretty.last_request().headers['Host'], 'nsmaster:8081')
  54. httpretty.reset()
  55. httpretty.register_uri(httpretty.DELETE, settings.NSLORD_PDNS_API + '/zones/' + self.ownedDomains[1].name + '.')
  56. httpretty.register_uri(httpretty.DELETE, settings.NSMASTER_PDNS_API + '/zones/' + self.ownedDomains[1].name+ '.')
  57. response = self.client.get(url)
  58. self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
  59. self.assertTrue(isinstance(httpretty.last_request(), httpretty.core.HTTPrettyRequestEmpty))
  60. def testCantDeleteOtherDomains(self):
  61. httpretty.enable()
  62. httpretty.register_uri(httpretty.DELETE, settings.NSLORD_PDNS_API + '/zones/' + self.otherDomains[1].name + '.')
  63. httpretty.register_uri(httpretty.DELETE, settings.NSMASTER_PDNS_API + '/zones/' + self.otherDomains[1].name+ '.')
  64. url = reverse('domain-detail', args=(self.otherDomains[1].pk,))
  65. response = self.client.delete(url)
  66. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
  67. self.assertTrue(isinstance(httpretty.last_request(), httpretty.core.HTTPrettyRequestEmpty))
  68. self.assertTrue(Domain.objects.filter(pk=self.otherDomains[1].pk).exists())
  69. def testCanGetOwnedDomains(self):
  70. httpretty.enable()
  71. httpretty.register_uri(httpretty.GET,
  72. settings.NSLORD_PDNS_API + '/zones/' + self.ownedDomains[1].name + './cryptokeys',
  73. body='[]',
  74. content_type="application/json")
  75. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  76. response = self.client.get(url)
  77. self.assertEqual(response.status_code, status.HTTP_200_OK)
  78. self.assertEqual(response.data['name'], self.ownedDomains[1].name)
  79. self.assertTrue(isinstance(response.data['keys'], list))
  80. def testCantGetOtherDomains(self):
  81. url = reverse('domain-detail', args=(self.otherDomains[1].pk,))
  82. response = self.client.get(url)
  83. self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
  84. def testCanPutOwnedDomain(self):
  85. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  86. response = self.client.get(url)
  87. response.data['arecord'] = '1.2.3.4'
  88. response = self.client.put(url, json.dumps(response.data), content_type='application/json')
  89. self.assertEqual(response.status_code, status.HTTP_200_OK)
  90. response = self.client.get(url)
  91. self.assertEqual(response.status_code, status.HTTP_200_OK)
  92. self.assertEqual(response.data['arecord'], '1.2.3.4')
  93. def testCantChangeDomainName(self):
  94. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  95. response = self.client.get(url)
  96. newname = utils.generateDomainname()
  97. response.data['name'] = newname
  98. response.data['arecord'] = None
  99. response.data['aaaarecord'] = None
  100. response = self.client.put(url, json.dumps(response.data), content_type='application/json')
  101. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  102. response = self.client.get(url)
  103. self.assertEqual(response.status_code, status.HTTP_200_OK)
  104. self.assertEqual(response.data['name'], self.ownedDomains[1].name)
  105. def testCantPutOtherDomains(self):
  106. url = reverse('domain-detail', args=(self.otherDomains[1].pk,))
  107. response = self.client.put(url, json.dumps({}), content_type='application/json')
  108. self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
  109. def testCanPostDomains(self):
  110. url = reverse('domain-list')
  111. data = {'name': utils.generateDomainname()}
  112. response = self.client.post(url, data)
  113. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  114. self.assertEqual(len(mail.outbox), 0)
  115. def testCanPostReverseDomains(self):
  116. name = '0.8.0.0.0.1.c.a.2.4.6.0.c.e.e.d.4.4.0.1.a.0.1.0.8.f.4.0.1.0.a.2.ip6.arpa'
  117. httpretty.enable()
  118. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones', status=201)
  119. httpretty.register_uri(httpretty.GET,
  120. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  121. body='{"rrsets": []}',
  122. content_type="application/json")
  123. url = reverse('domain-list')
  124. data = {'name': name}
  125. response = self.client.post(url, data)
  126. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  127. self.assertEqual(len(mail.outbox), 0)
  128. def testCantPostDomainAlreadyTakenInAPI(self):
  129. url = reverse('domain-list')
  130. data = {'name': utils.generateDomainname()}
  131. response = self.client.post(url, data)
  132. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  133. response = self.client.post(url, data)
  134. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  135. data = {'name': 'www.' + self.ownedDomains[0].name}
  136. response = self.client.post(url, data)
  137. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  138. data = {'name': 'www.' + self.otherDomains[0].name}
  139. response = self.client.post(url, data)
  140. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  141. def testCantPostDomainAlreadyTakenInPdns(self):
  142. name = utils.generateDomainname()
  143. httpretty.enable()
  144. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones',
  145. body='{"error": "Domain \'' + name + '.\' already exists"}', status=422)
  146. url = reverse('domain-list')
  147. data = {'name': name}
  148. response = self.client.post(url, data)
  149. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  150. def testCantPostDomainsViolatingPolicy(self):
  151. url = reverse('domain-list')
  152. data = {'name': '*.' + utils.generateDomainname()}
  153. response = self.client.post(url, data)
  154. self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
  155. self.assertTrue("does not match the required pattern." in response.data['name'][0])
  156. def testCanPostComplicatedDomains(self):
  157. url = reverse('domain-list')
  158. data = {'name': 'very.long.domain.name.' + utils.generateDomainname()}
  159. response = self.client.post(url, data)
  160. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  161. def testCanUpdateARecord(self):
  162. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  163. response = self.client.get(url)
  164. response.data['arecord'] = '10.13.3.7'
  165. response.data['aaaarecord'] = None
  166. response = self.client.put(url, json.dumps(response.data), content_type='application/json')
  167. self.assertEqual(response.status_code, status.HTTP_200_OK)
  168. response = self.client.get(url)
  169. self.assertEqual(response.status_code, status.HTTP_200_OK)
  170. self.assertEqual(response.data['arecord'], '10.13.3.7')
  171. def testCanUpdateAAAARecord(self):
  172. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  173. response = self.client.get(url)
  174. response.data['arecord'] = None
  175. response.data['aaaarecord'] = 'fe80::a11:10ff:fee0:ff77'
  176. response = self.client.put(url, json.dumps(response.data), content_type='application/json')
  177. self.assertEqual(response.status_code, status.HTTP_200_OK)
  178. response = self.client.get(url)
  179. self.assertEqual(response.status_code, status.HTTP_200_OK)
  180. self.assertEqual(response.data['aaaarecord'], 'fe80::a11:10ff:fee0:ff77')
  181. def testCanUpdateAcmeChallenge(self):
  182. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  183. response = self.client.get(url)
  184. response.data['acme_challenge'] = 'test_challenge'
  185. response = self.client.put(url, json.dumps(response.data), content_type='application/json')
  186. self.assertEqual(response.status_code, status.HTTP_200_OK)
  187. response = self.client.get(url)
  188. self.assertEqual(response.status_code, status.HTTP_200_OK)
  189. self.assertEqual(response.data['acme_challenge'], 'test_challenge')
  190. def testPostingCausesPdnsAPICalls(self):
  191. name = utils.generateDomainname()
  192. httpretty.enable()
  193. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  194. httpretty.register_uri(httpretty.GET,
  195. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  196. body='{"rrsets": []}',
  197. content_type="application/json")
  198. httpretty.register_uri(httpretty.GET,
  199. settings.NSLORD_PDNS_API + '/zones/' + name + './cryptokeys',
  200. body='[]',
  201. content_type="application/json")
  202. url = reverse('domain-list')
  203. self.client.post(url, {'name': name})
  204. self.assertEqual(httpretty.httpretty.latest_requests[-3].method, 'POST')
  205. self.assertTrue(name in httpretty.httpretty.latest_requests[-3].parsed_body)
  206. self.assertTrue('ns1.desec.io' in httpretty.httpretty.latest_requests[-3].parsed_body)
  207. self.assertEqual(httpretty.httpretty.latest_requests[-2].method, 'GET')
  208. self.assertTrue((settings.NSLORD_PDNS_API + '/zones/' + name + '.').endswith(httpretty.httpretty.latest_requests[-2].path))
  209. def testPostingWithRecordsCausesPdnsAPIPatch(self):
  210. name = utils.generateDomainname()
  211. httpretty.enable()
  212. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  213. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + name + '.')
  214. httpretty.register_uri(httpretty.GET,
  215. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  216. body='{"rrsets": []}',
  217. content_type="application/json")
  218. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + name + './notify')
  219. httpretty.register_uri(httpretty.GET,
  220. settings.NSLORD_PDNS_API + '/zones/' + name + './cryptokeys',
  221. body='[]',
  222. content_type="application/json")
  223. url = reverse('domain-list')
  224. data = {'name': name, 'arecord': '1.3.3.7', 'aaaarecord': 'dead::beef', 'acme_challenge': 'letsencrypt_ftw'}
  225. self.client.post(url, data)
  226. self.assertEqual(httpretty.httpretty.latest_requests[-4].method, 'PATCH')
  227. self.assertTrue(data['name'] in httpretty.httpretty.latest_requests[-4].parsed_body)
  228. self.assertTrue('1.3.3.7' in httpretty.httpretty.latest_requests[-4].parsed_body)
  229. self.assertTrue('dead::beef' in httpretty.httpretty.latest_requests[-4].parsed_body)
  230. self.assertTrue('letsencrypt_ftw' in httpretty.httpretty.latest_requests[-4].parsed_body)
  231. def testPostDomainCausesPdnsAPIPatch(self):
  232. name = utils.generateDomainname()
  233. httpretty.enable()
  234. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  235. httpretty.register_uri(httpretty.GET,
  236. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  237. body='{"rrsets": []}',
  238. content_type="application/json")
  239. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + name + '.')
  240. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + name + './notify')
  241. httpretty.register_uri(httpretty.GET,
  242. settings.NSLORD_PDNS_API + '/zones/' + name + './cryptokeys',
  243. body='[]',
  244. content_type="application/json")
  245. url = reverse('domain-list')
  246. data = {'name': name, 'acme_challenge': 'letsencrypt_ftw'}
  247. self.client.post(url, data)
  248. self.assertEqual(httpretty.httpretty.latest_requests[-4].method, 'PATCH')
  249. self.assertTrue(data['name'] in httpretty.httpretty.latest_requests[-4].parsed_body)
  250. self.assertTrue('letsencrypt_ftw' in httpretty.httpretty.latest_requests[-4].parsed_body)
  251. def testUpdateingCausesPdnsAPIPatchCall(self):
  252. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  253. response = self.client.get(url)
  254. httpretty.enable()
  255. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + '.')
  256. httpretty.register_uri(httpretty.GET,
  257. settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + '.',
  258. body='{"rrsets": []}',
  259. content_type="application/json")
  260. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + './notify')
  261. httpretty.register_uri(httpretty.GET,
  262. settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + './cryptokeys',
  263. body='[]',
  264. content_type="application/json")
  265. response.data['arecord'] = '10.13.3.7'
  266. self.client.put(url, json.dumps(response.data), content_type='application/json')
  267. self.assertTrue('10.13.3.7' in httpretty.httpretty.latest_requests[-4].parsed_body)
  268. def testUpdateingCausesPdnsAPINotifyCall(self):
  269. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  270. response = self.client.get(url)
  271. httpretty.enable()
  272. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + '.')
  273. httpretty.register_uri(httpretty.GET,
  274. settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + '.',
  275. body='{"rrsets": []}',
  276. content_type="application/json")
  277. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + './notify')
  278. httpretty.register_uri(httpretty.GET,
  279. settings.NSLORD_PDNS_API + '/zones/' + response.data['name'] + './cryptokeys',
  280. body='[]',
  281. content_type="application/json")
  282. response.data['arecord'] = '10.13.3.10'
  283. self.client.put(url, json.dumps(response.data), content_type='application/json')
  284. self.assertEqual(httpretty.httpretty.latest_requests[-4].method, 'PATCH')
  285. self.assertTrue('10.13.3.10' in httpretty.httpretty.latest_requests[-4].parsed_body)
  286. self.assertEqual(httpretty.httpretty.latest_requests[-2].method, 'PUT')
  287. def testDomainDetailURL(self):
  288. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  289. urlByName = reverse('domain-detail/byName', args=(self.ownedDomains[1].name,))
  290. self.assertTrue(("/%d" % self.ownedDomains[1].pk) in url)
  291. self.assertTrue("/" + self.ownedDomains[1].name in urlByName)
  292. def testRollback(self):
  293. name = utils.generateDomainname()
  294. httpretty.enable()
  295. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones', body="some error", status=500)
  296. url = reverse('domain-list')
  297. data = {'name': name}
  298. self.client.post(url, data)
  299. self.assertFalse(Domain.objects.filter(name=name).exists())
  300. class AuthenticatedDynDomainTests(APITestCase):
  301. def setUp(self):
  302. if not hasattr(self, 'owner'):
  303. self.owner = utils.createUser(dyn=True)
  304. self.ownedDomains = [utils.createDomain(self.owner, dyn=True), utils.createDomain(self.owner, dyn=True)]
  305. self.otherDomains = [utils.createDomain(), utils.createDomain()]
  306. self.token = utils.createToken(user=self.owner)
  307. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
  308. def tearDown(self):
  309. httpretty.reset()
  310. httpretty.disable()
  311. def testCanDeleteOwnedDynDomain(self):
  312. httpretty.enable()
  313. httpretty.register_uri(httpretty.DELETE, settings.NSLORD_PDNS_API + '/zones/' + self.ownedDomains[1].name + '.')
  314. httpretty.register_uri(httpretty.DELETE, settings.NSMASTER_PDNS_API + '/zones/' + self.ownedDomains[1].name+ '.')
  315. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/dedyn.io.')
  316. url = reverse('domain-detail', args=(self.ownedDomains[1].pk,))
  317. response = self.client.delete(url)
  318. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
  319. self.assertEqual(httpretty.last_request().method, 'PATCH')
  320. self.assertEqual(httpretty.last_request().headers['Host'], 'nslord:8081')
  321. self.assertTrue('"NS"' in httpretty.last_request().parsed_body)
  322. self.assertTrue('"' + self.ownedDomains[1].name + '."' in httpretty.last_request().parsed_body)
  323. self.assertTrue('"DELETE"' in httpretty.last_request().parsed_body)
  324. httpretty.reset()
  325. httpretty.register_uri(httpretty.DELETE, settings.NSLORD_PDNS_API + '/zones/' + self.ownedDomains[1].name + '.')
  326. httpretty.register_uri(httpretty.DELETE, settings.NSMASTER_PDNS_API + '/zones/' + self.ownedDomains[1].name+ '.')
  327. response = self.client.get(url)
  328. self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
  329. self.assertTrue(isinstance(httpretty.last_request(), httpretty.core.HTTPrettyRequestEmpty))
  330. def testCantDeleteOtherDynDomains(self):
  331. httpretty.enable()
  332. httpretty.register_uri(httpretty.DELETE, settings.NSLORD_PDNS_API + '/zones/' + self.otherDomains[1].name + '.')
  333. httpretty.register_uri(httpretty.DELETE, settings.NSMASTER_PDNS_API + '/zones/' + self.otherDomains[1].name+ '.')
  334. url = reverse('domain-detail', args=(self.otherDomains[1].pk,))
  335. response = self.client.delete(url)
  336. self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
  337. self.assertTrue(isinstance(httpretty.last_request(), httpretty.core.HTTPrettyRequestEmpty))
  338. self.assertTrue(Domain.objects.filter(pk=self.otherDomains[1].pk).exists())
  339. def testCanPostDynDomains(self):
  340. url = reverse('domain-list')
  341. data = {'name': utils.generateDynDomainname()}
  342. response = self.client.post(url, data)
  343. email = str(mail.outbox[0].message())
  344. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  345. self.assertEqual(len(mail.outbox), 1)
  346. self.assertTrue(data['name'] in email)
  347. self.assertTrue(self.token in email)
  348. def testCantPostNonDynDomains(self):
  349. url = reverse('domain-list')
  350. data = {'name': utils.generateDomainname()}
  351. response = self.client.post(url, data)
  352. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  353. self.assertEqual(response.data['code'], 'domain-illformed')
  354. data = {'name': 'very.long.domain.' + utils.generateDynDomainname()}
  355. response = self.client.post(url, data)
  356. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  357. self.assertEqual(response.data['code'], 'domain-illformed')
  358. def testLimitDynDomains(self):
  359. httpretty.enable()
  360. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  361. outboxlen = len(mail.outbox)
  362. url = reverse('domain-list')
  363. for i in range(settings.LIMIT_USER_DOMAIN_COUNT_DEFAULT-2):
  364. name = utils.generateDynDomainname()
  365. httpretty.register_uri(httpretty.GET,
  366. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  367. body='{"rrsets": []}',
  368. content_type="application/json")
  369. httpretty.register_uri(httpretty.GET,
  370. settings.NSLORD_PDNS_API + '/zones/' + name + './cryptokeys',
  371. body='[]',
  372. content_type="application/json")
  373. response = self.client.post(url, {'name': name})
  374. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  375. self.assertEqual(len(mail.outbox), outboxlen+i+1)
  376. data = {'name': utils.generateDynDomainname()}
  377. response = self.client.post(url, data)
  378. self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
  379. self.assertEqual(len(mail.outbox), outboxlen + settings.LIMIT_USER_DOMAIN_COUNT_DEFAULT-2)
  380. def testCantUseInvalidCharactersInDomainNamePDNS(self):
  381. httpretty.enable()
  382. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  383. outboxlen = len(mail.outbox)
  384. invalidnames = [
  385. 'with space.dedyn.io',
  386. 'another space.de',
  387. ' spaceatthebeginning.com',
  388. 'percentage%sign.com',
  389. '%percentagesign.dedyn.io',
  390. 'slash/desec.io',
  391. '/slashatthebeginning.dedyn.io',
  392. '\\backslashatthebeginning.dedyn.io',
  393. 'backslash\\inthemiddle.at',
  394. '@atsign.com',
  395. 'at@sign.com',
  396. ]
  397. url = reverse('domain-list')
  398. for domainname in invalidnames:
  399. data = {'name': domainname}
  400. response = self.client.post(url, data)
  401. self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
  402. self.assertEqual(len(mail.outbox), outboxlen)