Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added invite function

  • Loading branch information...
commit 51f4e0dc1c752acb471d8da7491fef2b2718511b 1 parent 430a34a
Christoph Eberhardt ceberhardt authored

Showing 3 changed files with 178 additions and 21 deletions. Show diff stats Hide diff stats

  1. +60 13 emailauth/forms.py
  2. +43 7 emailauth/models.py
  3. +75 1 emailauth/views.py
73 emailauth/forms.py
@@ -5,6 +5,7 @@
5 5 from django.contrib.auth.models import User
6 6
7 7 from emailauth.models import UserEmail
  8 +from uuid import uuid4
8 9
9 10 attrs_dict = {}
10 11
@@ -60,7 +61,7 @@ class RegistrationForm(forms.Form):
60 61 label=_(u'password'))
61 62 password2 = forms.CharField(widget=forms.PasswordInput(render_value=False),
62 63 label=_(u'password (again)'))
63   -
  64 +
64 65 clean_password2 = clean_password2
65 66
66 67 def clean_email(self):
@@ -72,7 +73,7 @@ def clean_email(self):
72 73 except UserEmail.DoesNotExist:
73 74 pass
74 75 return email
75   -
  76 +
76 77
77 78 def save(self):
78 79 data = self.cleaned_data
@@ -80,23 +81,69 @@ def save(self):
80 81 user.email = data['email']
81 82 user.first_name = data['name']
82 83 user.set_password(data['password1'])
  84 + user.username = ('%s' % (uuid4()))[:get_max_length(User, 'username')]
  85 + user.is_active = False
83 86 user.save()
84 87
85   - desired_username = 'id_%d_%s' % (user.id, user.email)
86   - user.username = desired_username[:get_max_length(User, 'username')]
  88 +# registration_profile = (
  89 +# RegistrationProfile.objects.create_inactive_profile(user))
  90 +# registration_profile.save()
  91 +#
  92 +# profile = Account()
  93 +# profile.user = user
  94 +# profile.save()
  95 +
  96 + return user #, registration_profile
  97 +
  98 +class InviteForm(forms.Form):
  99 + email = forms.EmailField(label=_(u'email address'))
  100 + network_name = forms.CharField(label=_(u'network name'))
  101 +
  102 + def clean_email(self):
  103 + email = self.cleaned_data['email']
  104 +
  105 + try:
  106 + user = UserEmail.objects.get(email=email)
  107 + raise forms.ValidationError(_(u'This email is already taken.'))
  108 + except UserEmail.DoesNotExist:
  109 + pass
  110 + return email
  111 +
  112 + def save(self):
  113 + data = self.cleaned_data
  114 + user = User()
  115 + user.email = data['email']
  116 + user.set_password(uuid4())
  117 + user.username = ('%s' % (uuid4()))[:get_max_length(User, 'username')]
87 118 user.is_active = False
88 119 user.save()
89   -
90   - registration_profile = (
91   - RegistrationProfile.objects.create_inactive_profile(user))
92   - registration_profile.save()
93 120
94   - profile = Account()
95   - profile.user = user
96   - profile.save()
  121 +class RegistrationAfterInviteForm(forms.Form):
  122 +
  123 + first_name = forms.CharField(label=_(u'first name'),
  124 + max_length=get_max_length(User, 'first_name'),
  125 + help_text=_(u"That's how we'll call you in emails"))
  126 + password1 = forms.CharField(widget=forms.PasswordInput(render_value=False),
  127 + label=_(u'password'))
  128 + password2 = forms.CharField(widget=forms.PasswordInput(render_value=False),
  129 + label=_(u'password (again)'))
  130 +
  131 + email = None
97 132
98   - return user, registration_profile
  133 + def __init__(self, *args, **kwargs):
  134 + self.email = kwargs.pop('email')
  135 + super(RegistrationAfterInviteForm, self).__init__(*args, **kwargs)
99 136
  137 + clean_password2 = clean_password2
  138 +
  139 + def save(self):
  140 + data = self.cleaned_data
  141 + user = UserEmail.objects.get(email=self.email).user
  142 + user.first_name = data['first_name']
  143 + user.set_password(data['password1'])
  144 + user.is_active = True
  145 + user.save()
  146 + return user
100 147
101 148 class PasswordResetRequestForm(forms.Form):
102 149 email = forms.EmailField(label=_(u'your email address'))
@@ -115,7 +162,7 @@ class PasswordResetForm(forms.Form):
115 162 label=_(u'password'))
116 163 password2 = forms.CharField(widget=forms.PasswordInput(render_value=False),
117 164 label=_(u'password (again)'))
118   -
  165 +
119 166 clean_password2 = clean_password2
120 167
121 168
50 emailauth/models.py
@@ -23,14 +23,20 @@ def make_random_key(self, email):
23 23 key = sha_constructor(salt + email).hexdigest()
24 24 return key
25 25
26   - def create_unverified_email(self, email, user=None):
  26 + def create_unverified_email(self, email, user=None, invite=False):
27 27 if use_automaintenance():
28 28 self.delete_expired()
29   -
  29 +
30 30 email_obj = UserEmail(email=email, user=user, default=user is None,
31   - verification_key=self.make_random_key(email))
  31 + verification_key=self.make_random_key(email), invite=invite)
32 32 return email_obj
33 33
  34 + def is_to_verify(self, verification_key):
  35 + try:
  36 + return self.get(verification_key=verification_key)
  37 + except self.model.DoesNotExist:
  38 + return None
  39 +
34 40 def verify(self, verification_key):
35 41 try:
36 42 email = self.get(verification_key=verification_key)
@@ -46,7 +52,7 @@ def delete_expired(self):
46 52 date_threshold = (datetime.datetime.now() -
47 53 datetime.timedelta(days=email_verification_days()))
48 54 expired_emails = self.filter(code_creation_date__lt=date_threshold)
49   -
  55 +
50 56 for email in expired_emails:
51 57 if not email.verified:
52 58 user = email.user
@@ -72,6 +78,8 @@ class Meta:
72 78 verified = models.BooleanField(default=False)
73 79 code_creation_date = models.DateTimeField(default=datetime.datetime.now)
74 80 verification_key = models.CharField(_('verification key'), max_length=40)
  81 + invite = models.BooleanField(default=False)
  82 + network_name = models.CharField(_('network_name'), max_length=40)
75 83
76 84 def __init__(self, *args, **kwds):
77 85 super(UserEmail, self).__init__(*args, **kwds)
@@ -97,7 +105,7 @@ def make_new_key(self):
97 105
98 106 def send_verification_email(self, first_name=None):
99 107 current_site = Site.objects.get_current()
100   -
  108 +
101 109 subject = render_to_string('emailauth/verification_email_subject.txt',
102 110 {'site': current_site})
103 111 # Email subject *must not* contain newlines
@@ -112,7 +120,7 @@ def send_verification_email(self, first_name=None):
112 120
113 121 if first_name is None:
114 122 first_name = self.user.first_name
115   -
  123 +
116 124 message = render_to_string('emailauth/verification_email.txt', {
117 125 'verification_key': self.verification_key,
118 126 'expiration_days': email_verification_days(),
@@ -125,7 +133,7 @@ def send_verification_email(self, first_name=None):
125 133
126 134 django.core.mail.send_mail(subject, message,
127 135 settings.DEFAULT_FROM_EMAIL, [self.email])
128   -
  136 +
129 137
130 138 def verification_key_expired(self):
131 139 expiration_date = datetime.timedelta(days=email_verification_days())
@@ -133,3 +141,31 @@ def verification_key_expired(self):
133 141 (self.code_creation_date + expiration_date <= datetime.datetime.now()))
134 142
135 143 verification_key_expired.boolean = True
  144 +
  145 + def send_invite_email(self, network_name):
  146 + current_site = Site.objects.get_current()
  147 +
  148 + subject = render_to_string('emailauth/invite_email_subject.txt',
  149 + {'site': current_site})
  150 + # Email subject *must not* contain newlines
  151 + subject = ''.join(subject.splitlines())
  152 +
  153 + emails = set()
  154 + if self.user is not None:
  155 + for email in self.__class__.objects.filter(user=self.user):
  156 + emails.add(email.email)
  157 + emails.add(self.email)
  158 + first_email = len(emails) == 1
  159 +
  160 + message = render_to_string('emailauth/invite_email.txt', {
  161 + 'verification_key': self.verification_key,
  162 + 'expiration_days': email_verification_days(),
  163 + 'site': current_site,
  164 + 'first_email': first_email,
  165 + 'network_name': network_name,
  166 + })
  167 +
  168 + self.code_creation_date = datetime.datetime.now()
  169 +
  170 + django.core.mail.send_mail(subject, message,
  171 + settings.DEFAULT_FROM_EMAIL, [self.email])
76 emailauth/views.py
@@ -20,7 +20,7 @@
20 20
21 21 from emailauth.forms import (LoginForm, RegistrationForm,
22 22 PasswordResetRequestForm, PasswordResetForm, AddEmailForm, DeleteEmailForm,
23   - ConfirmationForm)
  23 + ConfirmationForm, InviteForm, RegistrationAfterInviteForm)
24 24 from emailauth.models import UserEmail
25 25
26 26 from emailauth.utils import (use_single_email, requires_single_email_mode,
@@ -151,6 +151,77 @@ def register_continue(request, email,
151 151 return render_to_response(template_name, {'email': email},
152 152 RequestContext(request))
153 153
  154 +def default_invite_callback(form, email):
  155 + data = form.cleaned_data
  156 + user = User()
  157 + user.is_active = False
  158 + user.email = email.email
  159 + user.set_password(uuid4())
  160 + user.username = ('%s' % (uuid4()))[:get_max_length(User, 'username')]
  161 + user.save()
  162 + email.user = user
  163 +
  164 +def invite(request, callback=default_invite_callback):
  165 + if request.method == 'POST':
  166 + form = InviteForm(request.POST)
  167 + if form.is_valid():
  168 + email_obj = UserEmail.objects.create_unverified_email(
  169 + form.cleaned_data['email'], invite=True)
  170 + email_obj.send_invite_email(form.cleaned_data['network_name'])
  171 +
  172 + if callback is not None:
  173 + callback(form, email_obj)
  174 +
  175 + site = Site.objects.get_current()
  176 + email_obj.user.message_set.create(message='Welcome to %s.' % site.name)
  177 +
  178 + email_obj.network_name = form.cleaned_data['network_name']
  179 +
  180 + email_obj.save()
  181 + return HttpResponseRedirect(reverse('emailauth_invite_continue',
  182 + args=[quote_plus(email_obj.email)]))
  183 + else:
  184 + form = InviteForm()
  185 +
  186 + return render_to_response('emailauth/invite.html', {'form': form},
  187 + RequestContext(request))
  188 +
  189 +
  190 +def invite_continue(request, email,
  191 + template_name='emailauth/invite_continue.html'):
  192 +
  193 + return render_to_response(template_name, {'email': email},
  194 + RequestContext(request))
  195 +
  196 +def default_register_after_invite_callback(form, email):
  197 + data = form.cleaned_data
  198 + user = email.user
  199 + user.first_name = data['first_name']
  200 + user.is_active = True
  201 + user.set_password(data['password1'])
  202 + user.save()
  203 + email.user = user
  204 +
  205 +def register_after_invite(request, email, verification_key, callback=default_register_after_invite_callback):
  206 + if request.method == 'POST':
  207 + form = RegistrationAfterInviteForm(request.POST, email=email)
  208 + if form.is_valid():
  209 + from django.contrib.auth import login
  210 + email_obj = UserEmail.objects.verify(verification_key)
  211 + if not email_obj.verified or not email_obj.invite:
  212 + return HttpResponseRedirect(settings.LOGIN_URL)
  213 + if callback is not None:
  214 + callback(form, email_obj)
  215 + email_obj.user.backend = 'emailauth.backends.EmailBackend'
  216 + login(request, email_obj.user)
  217 + return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
  218 + else:
  219 + form = RegistrationForm()
  220 +
  221 + return render_to_response('emailauth/register_after_invite.html', {'form': form,
  222 + 'email': email},
  223 + RequestContext(request))
  224 +
154 225
155 226 def default_verify_callback(request, email):
156 227 email.user.is_active = True
@@ -170,6 +241,9 @@ def verify(request, verification_key, template_name='emailauth/verify.html',
170 241 extra_context=None, callback=default_verify_callback):
171 242
172 243 verification_key = verification_key.lower() # Normalize before trying anything with it.
  244 + email = UserEmail.objects.is_to_verify(verification_key)
  245 + if email and email.invite and email.verification_key:
  246 + return register_after_invite(request, email, verification_key)
173 247 email = UserEmail.objects.verify(verification_key)
174 248
175 249

0 comments on commit 51f4e0d

Please sign in to comment.
Something went wrong with that request. Please try again.