models.py 5.9 KB

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