forked from jtauber-archive/django-email-confirmation
/
models.py
120 lines (91 loc) · 3.64 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from datetime import datetime, timedelta
from random import random
import sha
from django.db import models, IntegrityError
from django.template.loader import render_to_string
# favour django-mailer but fall back to django.core.mail
try:
from mailer import send_mail
except ImportError:
from django.core.mail import send_mail
from django.conf import settings
from django.contrib.auth.models import User
# this code based in-part on django-registration
class EmailAddressManager(models.Manager):
def add_email(self, user, email):
try:
email_address = self.create(user=user, email=email)
EmailConfirmation.objects.send_confirmation(email_address)
return email_address
except IntegrityError:
return None
def get_primary(self, user):
try:
return self.get(user=user, primary=True)
except EmailAddress.DoesNotExist:
return None
class EmailAddress(models.Model):
user = models.ForeignKey(User)
email = models.EmailField()
verified = models.BooleanField(default=False)
primary = models.BooleanField(default=False)
objects = EmailAddressManager()
def set_as_primary(self, conditional=False):
old_primary = EmailAddress.objects.get_primary(self.user)
if old_primary:
if conditional:
return False
old_primary.primary = False
old_primary.save()
self.primary = True
self.save()
self.user.email = self.email
self.user.save()
return True
def __unicode__(self):
return u"%s (%s)" % (self.email, self.user)
class Meta:
unique_together = (
("user", "email"),
)
class Admin:
pass
class EmailConfirmationManager(models.Manager):
def confirm_email(self, confirmation_key):
try:
confirmation = self.get(confirmation_key=confirmation_key)
except self.model.DoesNotExist:
return None
if not confirmation.key_expired():
email_address = confirmation.email_address
email_address.verified = True
email_address.set_as_primary(conditional=True)
email_address.save()
return email_address
def send_confirmation(self, email_address):
salt = sha.new(str(random())).hexdigest()[:5]
confirmation_key = sha.new(salt + email_address.email).hexdigest()
subject = render_to_string("emailconfirmation/email_confirmation_subject.txt")
message = render_to_string("emailconfirmation/email_confirmation_message.txt", {
"user": email_address.user,
"confirmation_key": confirmation_key,
})
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email_address.email])
return self.create(email_address=email_address, sent=datetime.now(), confirmation_key=confirmation_key)
def delete_expired_confirmations(self):
for confirmation in self.all():
if confirmation.key_expired():
confirmate.delete()
class EmailConfirmation(models.Model):
email_address = models.ForeignKey(EmailAddress)
sent = models.DateTimeField()
confirmation_key = models.CharField(max_length=40)
objects = EmailConfirmationManager()
def key_expired(self):
expiration_date = self.sent + timedelta(days=settings.EMAIL_CONFIRMATION_DAYS)
return expiration_date <= datetime.now()
key_expired.boolean = True
def __unicode__(self):
return u"confirmation for %s" % self.email_address
class Admin:
pass