CCrypto VPN public website https://vpn.ccrypto.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

168 lines
5.2 KiB

  1. import random
  2. from datetime import timedelta
  3. from django.db import models
  4. from django.contrib.auth.models import User
  5. from django.utils.translation import ugettext as _
  6. from django.utils import timezone
  7. from django.db.models.signals import post_save
  8. from django.dispatch import receiver
  9. from constance import config as site_config
  10. from . import core
  11. from ccvpn.common import get_trial_period_duration
  12. from payments.models import Subscription
  13. prng = random.SystemRandom()
  14. def random_gift_code():
  15. charset = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"
  16. return ''.join([prng.choice(charset) for n in range(10)])
  17. class VPNUser(models.Model):
  18. class Meta:
  19. verbose_name = _("VPN User")
  20. verbose_name_plural = _("VPN Users")
  21. user = models.OneToOneField(User, on_delete=models.CASCADE)
  22. notes = models.TextField(blank=True)
  23. expiration = models.DateTimeField(blank=True, null=True)
  24. last_expiry_notice = models.DateTimeField(blank=True, null=True)
  25. notify_expiration = models.BooleanField(default=True)
  26. trial_periods_given = models.IntegerField(default=0)
  27. last_vpn_auth = models.DateTimeField(blank=True, null=True)
  28. referrer = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL,
  29. related_name='referrals')
  30. referrer_used = models.BooleanField(default=False)
  31. campaign = models.CharField(blank=True, null=True, max_length=64)
  32. @property
  33. def is_paid(self):
  34. if self.get_subscription():
  35. return True
  36. if not self.expiration:
  37. return False
  38. return self.expiration > timezone.now()
  39. @property
  40. def time_left(self):
  41. return timezone.now() - self.expiration
  42. def add_paid_time(self, time):
  43. now = timezone.now()
  44. if not self.expiration or self.expiration < now:
  45. self.expiration = now
  46. self.expiration += time
  47. # Propagate update to core
  48. if core.VPN_AUTH_STORAGE == 'core':
  49. core.update_user_expiration(self.user)
  50. def give_trial_period(self):
  51. self.add_paid_time(get_trial_period_duration())
  52. self.trial_periods_given += 1
  53. @property
  54. def can_have_trial(self):
  55. if self.trial_periods_given >= site_config.TRIAL_PERIOD_MAX:
  56. return False
  57. if self.user.payment_set.filter(status='confirmed').count() > 0:
  58. return False
  59. return True
  60. @property
  61. def remaining_trial_periods(self):
  62. return site_config.TRIAL_PERIOD_MAX - self.trial_periods_given
  63. def on_payment_confirmed(self, payment):
  64. if self.referrer and not self.referrer_used:
  65. self.referrer.vpnuser.add_paid_time(timedelta(days=14))
  66. self.referrer.vpnuser.save()
  67. self.referrer_used = True
  68. def get_subscription(self, include_unconfirmed=False):
  69. """ Tries to get the active (and most recent) Subscription """
  70. s = Subscription.objects.filter(user=self.user, status='active') \
  71. .order_by('-id') \
  72. .first()
  73. if s is not None or include_unconfirmed is False:
  74. return s
  75. s = Subscription.objects.filter(user=self.user, status='unconfirmed') \
  76. .order_by('-id') \
  77. .first()
  78. return s
  79. def __str__(self):
  80. return self.user.username
  81. @receiver(post_save, sender=User)
  82. def create_vpnuser(sender, instance, created, **kwargs):
  83. if created:
  84. VPNUser.objects.create(user=instance)
  85. class GiftCode(models.Model):
  86. class Meta:
  87. verbose_name = _("Gift Code")
  88. verbose_name_plural = _("Gift Codes")
  89. code = models.CharField(max_length=32, default=random_gift_code)
  90. time = models.DurationField(default=timedelta(days=30))
  91. created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
  92. created_by = models.ForeignKey(User, related_name='created_giftcode_set',
  93. on_delete=models.CASCADE, null=True, blank=True)
  94. single_use = models.BooleanField(default=True)
  95. free_only = models.BooleanField(default=True)
  96. available = models.BooleanField(default=True)
  97. comment = models.TextField(blank=True)
  98. users = models.ManyToManyField(User, through='GiftCodeUser')
  99. def use_on(self, user):
  100. if not self.available:
  101. return False
  102. if self.free_only and user.vpnuser.is_paid:
  103. return False
  104. link = GiftCodeUser(user=user, code=self)
  105. link.save()
  106. user.vpnuser.add_paid_time(self.time)
  107. user.vpnuser.save()
  108. if self.single_use:
  109. self.available = False
  110. self.save()
  111. return True
  112. @property
  113. def comment_head(self):
  114. head = self.comment.split('\n', 1)[0]
  115. if len(head) > 80:
  116. head = head[:80] + "..."
  117. return head
  118. def __str__(self):
  119. return self.code
  120. class GiftCodeUser(models.Model):
  121. class Meta:
  122. verbose_name = _("Gift Code User")
  123. verbose_name_plural = _("Gift Code Users")
  124. user = models.ForeignKey(User)
  125. code = models.ForeignKey(GiftCode)
  126. date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
  127. def __str__(self):
  128. return "%s (%s)" % (self.user.username, self.code.code)