test_dyndns12update.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import random
  2. from rest_framework import status
  3. from desecapi.tests.base import DynDomainOwnerTestCase
  4. class DynDNS12UpdateTest(DynDomainOwnerTestCase):
  5. def assertIP(self, ipv4=None, ipv6=None, name=None):
  6. name = name or self.my_domain.name.lower()
  7. for type_, value in [('A', ipv4), ('AAAA', ipv6)]:
  8. response = self.client_token_authorized.get(self.reverse('v1:rrset', name=name, subname='', type=type_))
  9. if value:
  10. self.assertStatus(response, status.HTTP_200_OK)
  11. self.assertEqual(response.data['records'][0], value)
  12. self.assertEqual(response.data['ttl'], 60)
  13. else:
  14. self.assertStatus(response, status.HTTP_404_NOT_FOUND)
  15. def test_identification_by_domain_name(self):
  16. self.client.set_credentials_basic_auth(self.my_domain.name + '.invalid', self.token.key)
  17. response = self.assertDynDNS12NoUpdate(mock_remote_addr='10.5.5.6')
  18. self.assertStatus(response, status.HTTP_401_UNAUTHORIZED)
  19. def test_identification_by_query_params(self):
  20. # /update?username=foobar.dedyn.io&password=secret
  21. self.client.set_credentials_basic_auth(None, None)
  22. response = self.assertDynDNS12Update(username=self.my_domain.name, password=self.token.key)
  23. self.assertStatus(response, status.HTTP_200_OK)
  24. self.assertEqual(response.data, 'good')
  25. self.assertIP(ipv4='127.0.0.1')
  26. def test_deviant_ttl(self):
  27. """
  28. The dynamic update will try to set the TTL to 60. Here, we create
  29. a record with a different TTL beforehand and then make sure that
  30. updates still work properly.
  31. """
  32. with self.assertPdnsRequests(
  33. self.request_pdns_zone_update(self.my_domain.name),
  34. self.request_pdns_zone_axfr(self.my_domain.name),
  35. ):
  36. response = self.client_token_authorized.patch_rr_set(
  37. self.my_domain.name.lower(), subname='', type_='A', ttl=3600)
  38. self.assertStatus(response, status.HTTP_200_OK)
  39. response = self.assertDynDNS12Update(self.my_domain.name)
  40. self.assertStatus(response, status.HTTP_200_OK)
  41. self.assertEqual(response.data, 'good')
  42. self.assertIP(ipv4='127.0.0.1')
  43. def test_ddclient_dyndns1_v4_success(self):
  44. # /nic/dyndns?action=edit&started=1&hostname=YES&host_id=foobar.dedyn.io&myip=10.1.2.3
  45. with self.assertPdnsRequests(
  46. self.request_pdns_zone_update(self.my_domain.name),
  47. self.request_pdns_zone_axfr(self.my_domain.name),
  48. ):
  49. response = self.client.get(
  50. self.reverse('v1:dyndns12update'),
  51. {
  52. 'action': 'edit',
  53. 'started': 1,
  54. 'hostname': 'YES',
  55. 'host_id': self.my_domain.name,
  56. 'myip': '10.1.2.3'
  57. }
  58. )
  59. self.assertStatus(response, status.HTTP_200_OK)
  60. self.assertEqual(response.data, 'good')
  61. self.assertIP(ipv4='10.1.2.3')
  62. def test_ddclient_dyndns1_v6_success(self):
  63. # /nic/dyndns?action=edit&started=1&hostname=YES&host_id=foobar.dedyn.io&myipv6=::1337
  64. response = self.assertDynDNS12Update(
  65. domain_name=self.my_domain.name,
  66. action='edit',
  67. started=1,
  68. hostname='YES',
  69. host_id=self.my_domain.name,
  70. myipv6='::1337'
  71. )
  72. self.assertStatus(response, status.HTTP_200_OK)
  73. self.assertEqual(response.data, 'good')
  74. self.assertIP(ipv4='127.0.0.1', ipv6='::1337')
  75. def test_ddclient_dyndns2_v4_success(self):
  76. # /nic/update?system=dyndns&hostname=foobar.dedyn.io&myip=10.2.3.4
  77. response = self.assertDynDNS12Update(
  78. domain_name=self.my_domain.name,
  79. system='dyndns',
  80. hostname=self.my_domain.name,
  81. myip='10.2.3.4',
  82. )
  83. self.assertStatus(response, status.HTTP_200_OK)
  84. self.assertEqual(response.data, 'good')
  85. self.assertIP(ipv4='10.2.3.4')
  86. def test_ddclient_dyndns2_v6_success(self):
  87. # /nic/update?system=dyndns&hostname=foobar.dedyn.io&myipv6=::1338
  88. response = self.assertDynDNS12Update(
  89. domain_name=self.my_domain.name,
  90. system='dyndns',
  91. hostname=self.my_domain.name,
  92. myipv6='::666',
  93. )
  94. self.assertStatus(response, status.HTTP_200_OK)
  95. self.assertEqual(response.data, 'good')
  96. self.assertIP(ipv4='127.0.0.1', ipv6='::666')
  97. def test_fritz_box(self):
  98. # /
  99. response = self.assertDynDNS12Update(self.my_domain.name)
  100. self.assertStatus(response, status.HTTP_200_OK)
  101. self.assertEqual(response.data, 'good')
  102. self.assertIP(ipv4='127.0.0.1')
  103. def test_unset_ip(self):
  104. for (v4, v6) in [
  105. ('127.0.0.1', '::1'),
  106. ('127.0.0.1', ''),
  107. ('', '::1'),
  108. ('', ''),
  109. ]:
  110. response = self.assertDynDNS12Update(self.my_domain.name, ip=v4, ipv6=v6)
  111. self.assertStatus(response, status.HTTP_200_OK)
  112. self.assertEqual(response.data, 'good')
  113. self.assertIP(ipv4=v4, ipv6=v6)
  114. class SingleDomainDynDNS12UpdateTest(DynDNS12UpdateTest):
  115. NUM_OWNED_DOMAINS = 1
  116. def test_identification_by_token(self):
  117. self.client.set_credentials_basic_auth('', self.token.key)
  118. response = self.assertDynDNS12Update(self.my_domain.name, mock_remote_addr='10.5.5.6')
  119. self.assertStatus(response, status.HTTP_200_OK)
  120. self.assertEqual(response.data, 'good')
  121. self.assertIP(ipv4='10.5.5.6')
  122. def test_identification_by_email(self):
  123. self.client.set_credentials_basic_auth(self.owner.email, self.token.key)
  124. response = self.assertDynDNS12Update(self.my_domain.name, mock_remote_addr='10.5.5.6')
  125. self.assertStatus(response, status.HTTP_200_OK)
  126. self.assertEqual(response.data, 'good')
  127. self.assertIP(ipv4='10.5.5.6')
  128. class MultipleDomainDynDNS12UpdateTest(DynDNS12UpdateTest):
  129. NUM_OWNED_DOMAINS = 4
  130. def test_identification_by_token(self):
  131. """
  132. Test if the conflict of having multiple domains, but not specifying which to update is correctly recognized.
  133. """
  134. self.client.set_credentials_basic_auth('', self.token.key)
  135. response = self.client.get(self.reverse('v1:dyndns12update'), REMOTE_ADDR='10.5.5.7')
  136. self.assertStatus(response, status.HTTP_409_CONFLICT)
  137. class MixedCaseDynDNS12UpdateTestCase(DynDNS12UpdateTest):
  138. @staticmethod
  139. def random_casing(s):
  140. return ''.join([c.lower() if random.choice([True, False]) else c.upper() for c in s])
  141. def setUp(self):
  142. super().setUp()
  143. self.my_domain.name = self.random_casing(self.my_domain.name)
  144. class UppercaseDynDNS12UpdateTestCase(DynDNS12UpdateTest):
  145. def setUp(self):
  146. super().setUp()
  147. self.my_domain.name = self.my_domain.name.upper()