testdyndns12update.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 django.db import transaction
  6. import base64
  7. import httpretty
  8. from django.conf import settings
  9. class DynDNS12UpdateTest(APITestCase):
  10. owner = None
  11. token = None
  12. username = None
  13. password = None
  14. def setUp(self):
  15. self.owner = utils.createUser()
  16. self.token = utils.createToken(user=self.owner)
  17. self.domain = utils.generateDynDomainname()
  18. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
  19. url = reverse('domain-list')
  20. data = {'name': self.domain}
  21. response = self.client.post(url, data)
  22. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  23. self.username = response.data['name']
  24. self.password = self.token
  25. self.client.credentials(HTTP_AUTHORIZATION='Basic ' + base64.b64encode((self.username + ':' + self.password).encode()).decode())
  26. httpretty.enable()
  27. httpretty.HTTPretty.allow_net_connect = False
  28. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  29. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.')
  30. httpretty.register_uri(httpretty.GET,
  31. settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.',
  32. body='{"rrsets": []}',
  33. content_type="application/json")
  34. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + self.domain + './notify')
  35. def tearDown(self):
  36. httpretty.reset()
  37. httpretty.disable()
  38. def assertIP(self, ipv4=None, ipv6=None):
  39. old_credentials = self.client._credentials['HTTP_AUTHORIZATION']
  40. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.password)
  41. url = reverse('domain-detail/byName', args=(self.username,))
  42. response = self.client.get(url)
  43. self.assertEqual(response.status_code, status.HTTP_200_OK)
  44. if ipv4 is not None:
  45. self.assertEqual(response.data['arecord'], ipv4)
  46. if ipv6 is not None:
  47. self.assertEqual(response.data['aaaarecord'], ipv6)
  48. self.client.credentials(HTTP_AUTHORIZATION=old_credentials)
  49. def testDynDNS1UpdateDDClientSuccess(self):
  50. # /nic/dyndns?action=edit&started=1&hostname=YES&host_id=foobar.dedyn.io&myip=10.1.2.3
  51. url = reverse('dyndns12update')
  52. response = self.client.get(url,
  53. {
  54. 'action': 'edit',
  55. 'started': 1,
  56. 'hostname': 'YES',
  57. 'host_id': self.username,
  58. 'myip': '10.1.2.3'
  59. })
  60. self.assertEqual(response.status_code, status.HTTP_200_OK)
  61. self.assertEqual(response.data, 'good')
  62. self.assertIP(ipv4='10.1.2.3')
  63. def testDynDNS1UpdateDDClientIPv6Success(self):
  64. # /nic/dyndns?action=edit&started=1&hostname=YES&host_id=foobar.dedyn.io&myipv6=::1337
  65. url = reverse('dyndns12update')
  66. response = self.client.get(url,
  67. {
  68. 'action': 'edit',
  69. 'started': 1,
  70. 'hostname': 'YES',
  71. 'host_id': self.username,
  72. 'myipv6': '::1337'
  73. })
  74. self.assertEqual(response.status_code, status.HTTP_200_OK)
  75. self.assertEqual(response.data, 'good')
  76. self.assertIP(ipv6='::1337')
  77. def testDynDNS2UpdateDDClientIPv4Success(self):
  78. #/nic/update?system=dyndns&hostname=foobar.dedyn.io&myip=10.2.3.4
  79. url = reverse('dyndns12update')
  80. response = self.client.get(url,
  81. {
  82. 'system': 'dyndns',
  83. 'hostname': self.username,
  84. 'myip': '10.2.3.4'
  85. })
  86. self.assertEqual(response.status_code, status.HTTP_200_OK)
  87. self.assertEqual(response.data, 'good')
  88. self.assertIP(ipv4='10.2.3.4')
  89. def testDynDNS2UpdateDDClientIPv6Success(self):
  90. #/nic/update?system=dyndns&hostname=foobar.dedyn.io&myipv6=::1338
  91. url = reverse('dyndns12update')
  92. response = self.client.get(url,
  93. {
  94. 'system': 'dyndns',
  95. 'hostname': self.username,
  96. 'myipv6': '::1338'
  97. })
  98. self.assertEqual(response.status_code, status.HTTP_200_OK)
  99. self.assertEqual(response.data, 'good')
  100. self.assertIP(ipv6='::1338')
  101. def testFritzBoxIPv6(self):
  102. #/
  103. url = reverse('dyndns12update')
  104. response = self.client.get(url)
  105. self.assertEqual(response.status_code, status.HTTP_200_OK)
  106. self.assertEqual(response.data, 'good')
  107. self.assertIP(ipv4='127.0.0.1')
  108. def testIdentificationByUsernameDomainname(self):
  109. # To force identification by the provided username (which is the domain name)
  110. # we add a second domain for the current user.
  111. name = 'second-' + self.domain
  112. httpretty.register_uri(httpretty.GET,
  113. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  114. body='{"rrsets": []}',
  115. content_type="application/json")
  116. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
  117. url = reverse('domain-list')
  118. response = self.client.post(url, {'name': name})
  119. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  120. self.client.credentials(HTTP_AUTHORIZATION='Basic ' + base64.b64encode((self.username + ':' + self.password).encode()).decode())
  121. url = reverse('dyndns12update')
  122. response = self.client.get(url, REMOTE_ADDR='10.5.5.5')
  123. self.assertEqual(response.status_code, status.HTTP_200_OK)
  124. self.assertEqual(response.data, 'good')
  125. self.assertIP(ipv4='10.5.5.5')
  126. self.client.credentials(HTTP_AUTHORIZATION='Basic ' + base64.b64encode((self.username + '.invalid:' + self.password).encode()).decode())
  127. url = reverse('dyndns12update')
  128. response = self.client.get(url, REMOTE_ADDR='10.5.5.5')
  129. self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
  130. def testIdentificationByTokenWithEmptyUser(self):
  131. self.client.credentials(HTTP_AUTHORIZATION='Basic ' + base64.b64encode((':' + self.password).encode()).decode())
  132. url = reverse('dyndns12update')
  133. response = self.client.get(url, REMOTE_ADDR='10.5.5.6')
  134. self.assertEqual(response.status_code, status.HTTP_200_OK)
  135. self.assertEqual(response.data, 'good')
  136. self.assertIP(ipv4='10.5.5.6')
  137. # Now make sure we get a conflict when the user has multiple domains. Thus,
  138. # we add a second domain for the current user.
  139. name = 'second-' + self.domain
  140. httpretty.register_uri(httpretty.GET,
  141. settings.NSLORD_PDNS_API + '/zones/' + name + '.',
  142. body='{"rrsets": []}',
  143. content_type="application/json")
  144. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
  145. url = reverse('domain-list')
  146. response = self.client.post(url, {'name': name})
  147. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  148. url = reverse('dyndns12update')
  149. response = self.client.get(url, REMOTE_ADDR='10.5.5.7')
  150. self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
  151. def testManualIPv6(self):
  152. #/update?username=foobar.dedyn.io&password=secret
  153. self.client.credentials(HTTP_AUTHORIZATION='')
  154. url = reverse('dyndns12update')
  155. response = self.client.get(url,
  156. {
  157. 'username': self.username,
  158. 'password': self.token,
  159. })
  160. self.assertEqual(response.status_code, status.HTTP_200_OK)
  161. self.assertEqual(response.data, 'good')
  162. self.assertIP(ipv4='127.0.0.1')
  163. def testSuspendedUpdates(self):
  164. self.owner.captcha_required = True
  165. self.owner.save()
  166. httpretty.reset()
  167. httpretty.enable()
  168. httpretty.HTTPretty.allow_net_connect = False
  169. domain = self.owner.domains.all()[0]
  170. domain.arecord = '10.1.1.1'
  171. domain.save()
  172. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.')
  173. httpretty.register_uri(httpretty.GET, settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.', status=200)
  174. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + self.domain + './notify', status=200)
  175. self.owner.unlock()
  176. self.assertEqual(httpretty.httpretty.latest_requests[-2].method, 'PATCH')
  177. self.assertTrue((settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.').endswith(httpretty.httpretty.latest_requests[-2].path))
  178. self.assertTrue(self.domain in httpretty.httpretty.latest_requests[-2].parsed_body)
  179. self.assertTrue('10.1.1.1' in httpretty.httpretty.latest_requests[-2].parsed_body)
  180. def testSuspendedUpdatesDomainCreation(self):
  181. self.owner.captcha_required = True
  182. self.owner.save()
  183. httpretty.reset()
  184. httpretty.enable()
  185. httpretty.HTTPretty.allow_net_connect = False
  186. url = reverse('domain-list')
  187. newdomain = utils.generateDynDomainname()
  188. data = {'name': newdomain, 'dyn': True, 'arecord': '10.2.2.2'}
  189. self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
  190. response = self.client.post(url, data)
  191. self.assertEqual(response.status_code, status.HTTP_201_CREATED)
  192. domain = self.owner.domains.all()[0]
  193. domain.arecord = '10.1.1.1'
  194. domain.save()
  195. httpretty.register_uri(httpretty.POST, settings.NSLORD_PDNS_API + '/zones')
  196. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + newdomain + '.')
  197. httpretty.register_uri(httpretty.GET, settings.NSLORD_PDNS_API + '/zones/' + newdomain + '.', status=200)
  198. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + newdomain + './notify', status=200)
  199. httpretty.register_uri(httpretty.PATCH, settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.')
  200. httpretty.register_uri(httpretty.GET, settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.', status=200)
  201. httpretty.register_uri(httpretty.PUT, settings.NSLORD_PDNS_API + '/zones/' + self.domain + './notify', status=200)
  202. self.owner.unlock()
  203. self.assertEqual(httpretty.httpretty.latest_requests[-2].method, 'PATCH')
  204. self.assertTrue(
  205. (settings.NSLORD_PDNS_API + '/zones/' + self.domain + '.').endswith(httpretty.httpretty.latest_requests[-2].path) \
  206. or (settings.NSLORD_PDNS_API + '/zones/' + newdomain + '.').endswith(httpretty.httpretty.latest_requests[-2].path)
  207. )
  208. self.assertTrue('10.2.2.2' in httpretty.httpretty.latest_requests[-2].parsed_body)