models.py 6.7 KB

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