test_authentication.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import base64
  2. import json
  3. import re
  4. from django.core import mail
  5. from rest_framework import status
  6. from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED
  7. from desecapi.models import Token, User
  8. from desecapi.tests.base import DynDomainOwnerTestCase, DesecTestCase
  9. class DynUpdateAuthenticationTestCase(DynDomainOwnerTestCase):
  10. NUM_OWNED_DOMAINS = 1
  11. def _get_dyndns12(self):
  12. with self.assertPdnsNoRequestsBut(self.requests_desec_rr_sets_update()):
  13. return self.client.get(self.reverse('v1:dyndns12update'))
  14. def assertDynDNS12Status(self, code=HTTP_200_OK, authorization=None):
  15. if authorization:
  16. self.client.set_credentials_basic_auth(authorization)
  17. self.assertStatus(self._get_dyndns12(), code)
  18. def test_username_password(self):
  19. # noinspection PyPep8Naming
  20. def assertDynDNS12AuthenticationStatus(username, token, code):
  21. self.client.set_credentials_basic_auth(username, token)
  22. self.assertDynDNS12Status(code)
  23. assertDynDNS12AuthenticationStatus('', self.token.key, HTTP_200_OK)
  24. assertDynDNS12AuthenticationStatus(self.owner.get_username(), self.token.key, HTTP_200_OK)
  25. assertDynDNS12AuthenticationStatus(self.my_domain.name, self.token.key, HTTP_200_OK)
  26. assertDynDNS12AuthenticationStatus(' ' + self.my_domain.name, self.token.key, HTTP_401_UNAUTHORIZED)
  27. assertDynDNS12AuthenticationStatus('wrong', self.token.key, HTTP_401_UNAUTHORIZED)
  28. assertDynDNS12AuthenticationStatus('', 'wrong', HTTP_401_UNAUTHORIZED)
  29. assertDynDNS12AuthenticationStatus(self.user.get_username(), 'wrong', HTTP_401_UNAUTHORIZED)
  30. def test_malformed_basic_auth(self):
  31. for authorization in [
  32. 'asdf:asdf:sadf',
  33. 'asdf',
  34. 'bull[%]shit',
  35. '你好',
  36. '💩💩💩💩',
  37. '💩💩:💩💩',
  38. ]:
  39. self.assertDynDNS12Status(authorization=authorization, code=HTTP_401_UNAUTHORIZED)
  40. class SignUpLoginTestCase(DesecTestCase):
  41. EMAIL = None
  42. PASSWORD = None
  43. REGISTRATION_ENDPOINT = None
  44. LOGIN_ENDPOINT = None
  45. REGISTRATION_STATUS = status.HTTP_202_ACCEPTED
  46. LOGIN_STATUS = status.HTTP_200_OK
  47. def __init__(self, *args, **kwargs):
  48. super().__init__(*args, **kwargs)
  49. self.EMAIL = self.random_username()
  50. self.PASSWORD = self.random_password()
  51. if not self.REGISTRATION_ENDPOINT:
  52. self.REGISTRATION_ENDPOINT = self.reverse('v1:register')
  53. if not self.LOGIN_ENDPOINT:
  54. self.LOGIN_ENDPOINT = self.reverse('v1:login')
  55. def sign_up(self):
  56. self.assertStatus(
  57. self.client.post(self.REGISTRATION_ENDPOINT, {
  58. 'email': self.EMAIL,
  59. 'password': self.PASSWORD,
  60. }),
  61. self.REGISTRATION_STATUS
  62. )
  63. def activate(self):
  64. total = 1
  65. self.assertEqual(len(mail.outbox), total, "Expected %i message in the outbox, but found %i." %
  66. (total, len(mail.outbox)))
  67. email = mail.outbox[-1]
  68. self.assertTrue('Welcome' in email.subject)
  69. confirmation_link = re.search(r'following link:\s+([^\s]*)', email.body).group(1)
  70. self.client.get(confirmation_link)
  71. def log_in(self):
  72. response = self.client.post(self.LOGIN_ENDPOINT, {
  73. 'email': self.EMAIL,
  74. 'password': self.PASSWORD,
  75. })
  76. self.assertContains(response, "auth_token", status_code=self.LOGIN_STATUS)
  77. def test_sign_up(self):
  78. self.sign_up()
  79. self.assertFalse(User.objects.get(email=self.EMAIL).is_active)
  80. def test_activate(self):
  81. self.sign_up()
  82. self.activate()
  83. self.assertTrue(User.objects.get(email=self.EMAIL).is_active)
  84. def test_log_in(self):
  85. self.sign_up()
  86. self.activate()
  87. self.log_in()
  88. def test_log_in_twice(self):
  89. self.sign_up()
  90. self.activate()
  91. self.log_in()
  92. self.log_in()
  93. def test_log_in_two_tokens(self):
  94. self.sign_up()
  95. self.activate()
  96. for _ in range(2):
  97. Token.objects.create(user=User.objects.get(email=self.EMAIL))
  98. self.log_in()
  99. class TokenAuthenticationTestCase(DynDomainOwnerTestCase):
  100. def _get_domains(self):
  101. with self.assertPdnsNoRequestsBut(self.request_pdns_zone_retrieve_crypto_keys()):
  102. return self.client.get(self.reverse('v1:domain-list'))
  103. def assertAuthenticationStatus(self, code=HTTP_200_OK, token=''):
  104. self.client.set_credentials_token_auth(token)
  105. self.assertStatus(self._get_domains(), code)
  106. def test_token_case_sensitive(self):
  107. self.assertAuthenticationStatus(HTTP_200_OK, self.token.key)
  108. self.assertAuthenticationStatus(HTTP_401_UNAUTHORIZED, self.token.key.upper())
  109. self.assertAuthenticationStatus(HTTP_401_UNAUTHORIZED, self.token.key.lower())