models.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. from django.conf import settings
  2. from django.db import models, transaction
  3. from django.contrib.auth.models import (
  4. BaseUserManager, AbstractBaseUser
  5. )
  6. from django.utils import timezone
  7. from django.core.exceptions import ValidationError
  8. from desecapi import pdns
  9. import datetime, time
  10. import django.core.exceptions
  11. import rest_framework.exceptions
  12. class MyUserManager(BaseUserManager):
  13. def create_user(self, email, password=None, registration_remote_ip=None, captcha_required=False):
  14. """
  15. Creates and saves a User with the given email, date of
  16. birth and password.
  17. """
  18. if not email:
  19. raise ValueError('Users must have an email address')
  20. user = self.model(
  21. email=self.normalize_email(email),
  22. registration_remote_ip=registration_remote_ip,
  23. captcha_required=captcha_required,
  24. )
  25. user.set_password(password)
  26. user.save(using=self._db)
  27. return user
  28. def create_superuser(self, email, password):
  29. """
  30. Creates and saves a superuser with the given email, date of
  31. birth and password.
  32. """
  33. user = self.create_user(email,
  34. password=password
  35. )
  36. user.is_admin = True
  37. user.save(using=self._db)
  38. return user
  39. class User(AbstractBaseUser):
  40. email = models.EmailField(
  41. verbose_name='email address',
  42. max_length=191,
  43. unique=True,
  44. )
  45. is_active = models.BooleanField(default=True)
  46. is_admin = models.BooleanField(default=False)
  47. registration_remote_ip = models.CharField(max_length=1024, blank=True)
  48. captcha_required = models.BooleanField(default=False)
  49. created = models.DateTimeField(auto_now_add=True)
  50. limit_domains = models.IntegerField(default=settings.LIMIT_USER_DOMAIN_COUNT_DEFAULT,null=True,blank=True)
  51. dyn = models.BooleanField(default=True)
  52. objects = MyUserManager()
  53. USERNAME_FIELD = 'email'
  54. REQUIRED_FIELDS = []
  55. def get_full_name(self):
  56. return self.email
  57. def get_short_name(self):
  58. return self.email
  59. def __str__(self):
  60. return self.email
  61. def has_perm(self, perm, obj=None):
  62. "Does the user have a specific permission?"
  63. # Simplest possible answer: Yes, always
  64. return True
  65. def has_module_perms(self, app_label):
  66. "Does the user have permissions to view the app `app_label`?"
  67. # Simplest possible answer: Yes, always
  68. return True
  69. @property
  70. def is_staff(self):
  71. "Is the user a member of staff?"
  72. # Simplest possible answer: All admins are staff
  73. return self.is_admin
  74. def unlock(self):
  75. self.captcha_required = False
  76. for domain in self.domains.all():
  77. domain.pdns_resync()
  78. self.save()
  79. class Domain(models.Model):
  80. created = models.DateTimeField(auto_now_add=True)
  81. updated = models.DateTimeField(null=True)
  82. name = models.CharField(max_length=191, unique=True)
  83. arecord = models.GenericIPAddressField(protocol='IPv4', blank=False, null=True)
  84. aaaarecord = models.GenericIPAddressField(protocol='IPv6', blank=False, null=True)
  85. owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='domains')
  86. acme_challenge = models.CharField(max_length=255, blank=True)
  87. _dirtyName = False
  88. _dirtyRecords = False
  89. def __setattr__(self, attrname, val):
  90. setter_func = 'setter_' + attrname
  91. if attrname in self.__dict__ and callable(getattr(self, setter_func, None)):
  92. super(Domain, self).__setattr__(attrname, getattr(self, setter_func)(val))
  93. else:
  94. super(Domain, self).__setattr__(attrname, val)
  95. def setter_name(self, val):
  96. if val != self.name:
  97. self._dirtyName = True
  98. return val
  99. def setter_arecord(self, val):
  100. if val != self.arecord:
  101. self._dirtyRecords = True
  102. return val
  103. def setter_aaaarecord(self, val):
  104. if val != self.aaaarecord:
  105. self._dirtyRecords = True
  106. return val
  107. def setter_acme_challenge(self, val):
  108. if val != self.acme_challenge:
  109. self._dirtyRecords = True
  110. return val
  111. def clean(self):
  112. if self._dirtyName:
  113. raise ValidationError('You must not change the domain name')
  114. def pdns_resync(self):
  115. """
  116. Make sure that pdns gets the latest information about this domain/zone.
  117. Re-Syncing is relatively expensive and should not happen routinely.
  118. """
  119. # Create zone if needed
  120. if not pdns.zone_exists(self.name):
  121. pdns.create_zone(self.name)
  122. # update zone to latest information
  123. pdns.set_dyn_records(self.name, self.arecord, self.aaaarecord, self.acme_challenge)
  124. def pdns_sync(self, new_domain):
  125. """
  126. Command pdns updates as indicated by the local changes.
  127. """
  128. if self.owner.captcha_required:
  129. # suspend all updates
  130. return
  131. # if this zone is new, create it and set dirty flag if necessary
  132. if new_domain:
  133. pdns.create_zone(self.name)
  134. self._dirtyRecords = bool(self.arecord) or bool(self.aaaarecord) or bool(self.acme_challenge)
  135. # make changes if necessary
  136. if self._dirtyRecords:
  137. pdns.set_dyn_records(self.name, self.arecord, self.aaaarecord, self.acme_challenge)
  138. self._dirtyRecords = False
  139. @transaction.atomic
  140. def delete(self, *args, **kwargs):
  141. super(Domain, self).delete(*args, **kwargs)
  142. pdns.delete_zone(self.name)
  143. if self.name.endswith('.dedyn.io'):
  144. pdns.set_rrset('dedyn.io', self.name, 'DS', '')
  145. pdns.set_rrset('dedyn.io', self.name, 'NS', '')
  146. @transaction.atomic
  147. def save(self, *args, **kwargs):
  148. # Record here if this is a new domain (self.pk is only None until we call super.save())
  149. new_domain = self.pk is None
  150. self.updated = timezone.now()
  151. self.clean()
  152. super(Domain, self).save(*args, **kwargs)
  153. self.pdns_sync(new_domain)
  154. class Meta:
  155. ordering = ('created',)
  156. def get_default_value_created():
  157. return timezone.now()
  158. def get_default_value_due():
  159. return timezone.now() + datetime.timedelta(days=7)
  160. def get_default_value_mref():
  161. return "ONDON" + str((timezone.now() - timezone.datetime(1970,1,1,tzinfo=timezone.utc)).total_seconds())
  162. class Donation(models.Model):
  163. created = models.DateTimeField(default=get_default_value_created)
  164. name = models.CharField(max_length=255)
  165. iban = models.CharField(max_length=34)
  166. bic = models.CharField(max_length=11)
  167. amount = models.DecimalField(max_digits=8,decimal_places=2)
  168. message = models.CharField(max_length=255, blank=True)
  169. due = models.DateTimeField(default=get_default_value_due)
  170. mref = models.CharField(max_length=32,default=get_default_value_mref)
  171. email = models.EmailField(max_length=255, blank=True)
  172. def save(self, *args, **kwargs):
  173. self.iban = self.iban[:6] + "xxx" # do NOT save account details
  174. super(Donation, self).save(*args, **kwargs) # Call the "real" save() method.
  175. class Meta:
  176. ordering = ('created',)