|
1 | | -import datetime |
2 | | -import hashlib |
3 | | -import subprocess |
| 1 | +import re |
4 | 2 |
|
5 | 3 | from django import forms |
6 | 4 | from django.forms import ModelForm |
7 | | -from django.conf import settings |
| 5 | +from django.db import models |
8 | 6 | from django.contrib.auth.models import User |
9 | | -from django.contrib.sites.models import Site |
10 | | -from django.utils.translation import ugettext_lazy as _ |
| 7 | +from django.utils.html import mark_safe |
| 8 | +from django.core.urlresolvers import reverse as urlreverse |
11 | 9 |
|
12 | | -from ietf.utils.mail import send_mail |
13 | | -from ietf.person.models import Person, Email, Alias |
14 | | -from ietf.group.models import Role |
| 10 | +from ietf.person.models import Person, Email |
15 | 11 |
|
16 | 12 |
|
17 | 13 | class RegistrationForm(forms.Form): |
18 | | - |
19 | 14 | email = forms.EmailField(label="Your email (lowercase)") |
20 | | - realm = 'IETF' |
21 | | - expire = 3 |
22 | | - |
23 | | - def save(self, *args, **kwargs): |
24 | | - # why is there a save when it doesn't save? |
25 | | - self.send_email() |
26 | | - return True |
27 | | - |
28 | | - def send_email(self): |
29 | | - domain = Site.objects.get_current().domain |
30 | | - subject = 'Confirm registration at %s' % domain |
31 | | - from_email = settings.DEFAULT_FROM_EMAIL |
32 | | - to_email = self.cleaned_data['email'] |
33 | | - today = datetime.date.today().strftime('%Y%m%d') |
34 | | - auth = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, today, to_email, self.realm)).hexdigest() |
35 | | - context = { |
36 | | - 'domain': domain, |
37 | | - 'today': today, |
38 | | - 'realm': self.realm, |
39 | | - 'auth': auth, |
40 | | - 'username': to_email, |
41 | | - 'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK, |
42 | | - } |
43 | | - send_mail(self.request, to_email, from_email, subject, 'registration/creation_email.txt', context) |
44 | 15 |
|
45 | 16 | def clean_email(self): |
46 | 17 | email = self.cleaned_data.get('email', '') |
47 | 18 | if not email: |
48 | 19 | return email |
49 | 20 | if email.lower() != email: |
50 | | - raise forms.ValidationError(_('The supplied address contained uppercase letters. Please use a lowercase email address.')) |
51 | | - if User.objects.filter(username=email).count(): |
52 | | - raise forms.ValidationError(_('An account with the email address you provided already exists.')) |
| 21 | + raise forms.ValidationError('The supplied address contained uppercase letters. Please use a lowercase email address.') |
| 22 | + if User.objects.filter(username=email).exists(): |
| 23 | + raise forms.ValidationError('An account with the email address you provided already exists.') |
53 | 24 | return email |
54 | 25 |
|
55 | 26 |
|
56 | | -class RecoverPasswordForm(RegistrationForm): |
57 | | - |
58 | | - realm = 'IETF' |
59 | | - |
60 | | - def send_email(self): |
61 | | - domain = Site.objects.get_current().domain |
62 | | - subject = 'Password reset at %s' % domain |
63 | | - from_email = settings.DEFAULT_FROM_EMAIL |
64 | | - today = datetime.date.today().strftime('%Y%m%d') |
65 | | - to_email = self.cleaned_data['email'] |
66 | | - today = datetime.date.today().strftime('%Y%m%d') |
67 | | - auth = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, today, to_email, self.realm)).hexdigest() |
68 | | - context = { |
69 | | - 'domain': domain, |
70 | | - 'today': today, |
71 | | - 'realm': self.realm, |
72 | | - 'auth': auth, |
73 | | - 'username': to_email, |
74 | | - 'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK, |
75 | | - } |
76 | | - send_mail(self.request, to_email, from_email, subject, 'registration/password_reset_email.txt', context) |
| 27 | +class PasswordForm(forms.Form): |
| 28 | + password = forms.CharField(widget=forms.PasswordInput) |
| 29 | + password_confirmation = forms.CharField(widget=forms.PasswordInput, |
| 30 | + help_text="Enter the same password as above, for verification.") |
77 | 31 |
|
78 | | - def clean_email(self): |
79 | | - email = self.cleaned_data.get('email', '') |
| 32 | + def clean_password_confirmation(self): |
| 33 | + password = self.cleaned_data.get("password", "") |
| 34 | + password_confirmation = self.cleaned_data["password_confirmation"] |
| 35 | + if password != password_confirmation: |
| 36 | + raise forms.ValidationError("The two password fields didn't match.") |
| 37 | + return password_confirmation |
| 38 | + |
| 39 | + |
| 40 | +def ascii_cleaner(supposedly_ascii): |
| 41 | + outside_printable_ascii_pattern = r'[^\x20-\x7F]' |
| 42 | + if re.search(outside_printable_ascii_pattern, supposedly_ascii): |
| 43 | + raise forms.ValidationError("Please only enter ASCII characters.") |
| 44 | + return supposedly_ascii |
| 45 | + |
| 46 | +class PersonForm(ModelForm): |
| 47 | + class Meta: |
| 48 | + model = Person |
| 49 | + exclude = ('time', 'user') |
| 50 | + |
| 51 | + def clean_ascii(self): |
| 52 | + return ascii_cleaner(self.cleaned_data.get("ascii") or u"") |
| 53 | + |
| 54 | + def clean_ascii_short(self): |
| 55 | + return ascii_cleaner(self.cleaned_data.get("ascii_short") or u"") |
| 56 | + |
| 57 | + |
| 58 | +class NewEmailForm(forms.Form): |
| 59 | + new_email = forms.EmailField(label="New email address", required=False) |
| 60 | + |
| 61 | + def clean_new_email(self): |
| 62 | + email = self.cleaned_data.get("new_email", "") |
| 63 | + if email: |
| 64 | + existing = Email.objects.filter(address=email).first() |
| 65 | + if existing: |
| 66 | + raise forms.ValidationError("Email address '%s' is already assigned to account '%s' (%s)" % (existing, existing.person and existing.person.user, existing.person)) |
80 | 67 | return email |
81 | 68 |
|
82 | 69 |
|
83 | | -class PasswordForm(forms.Form): |
| 70 | +class RoleEmailForm(forms.Form): |
| 71 | + email = forms.ModelChoiceField(label="Role email", queryset=Email.objects.all()) |
| 72 | + |
| 73 | + def __init__(self, role, *args, **kwargs): |
| 74 | + super(RoleEmailForm, self).__init__(*args, **kwargs) |
| 75 | + |
| 76 | + f = self.fields["email"] |
| 77 | + f.label = u"%s in %s" % (role.name, role.group.acronym.upper()) |
| 78 | + f.help_text = u"Email to use for <i>%s</i> role in %s" % (role.name, role.group.name) |
| 79 | + f.queryset = f.queryset.filter(models.Q(person=role.person_id) | models.Q(role=role)) |
| 80 | + f.initial = role.email_id |
| 81 | + f.choices = [(e.pk, e.address if e.active else u"({})".format(e.address)) for e in f.queryset] |
| 82 | + |
| 83 | + |
| 84 | +class ResetPasswordForm(forms.Form): |
| 85 | + username = forms.EmailField(label="Your email (lowercase)") |
| 86 | + |
| 87 | + def clean_username(self): |
| 88 | + import ietf.ietfauth.views |
| 89 | + username = self.cleaned_data["username"] |
| 90 | + if not User.objects.filter(username=username).exists(): |
| 91 | + raise forms.ValidationError(mark_safe("Didn't find a matching account. If you don't have an account yet, you can <a href=\"{}\">create one</a>.".format(urlreverse(ietf.ietfauth.views.create_account)))) |
| 92 | + return username |
84 | 93 |
|
85 | | - password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput) |
86 | | - password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput, |
87 | | - help_text=_("Enter the same password as above, for verification.")) |
88 | | - |
89 | | - def __init__(self, *args, **kwargs): |
90 | | - self.username = kwargs.pop('username') |
91 | | - self.update_user = User.objects.filter(username=self.username).count() > 0 |
92 | | - super(PasswordForm, self).__init__(*args, **kwargs) |
93 | | - |
94 | | - def clean_password2(self): |
95 | | - password1 = self.cleaned_data.get("password1", "") |
96 | | - password2 = self.cleaned_data["password2"] |
97 | | - if password1 != password2: |
98 | | - raise forms.ValidationError(_("The two password fields didn't match.")) |
99 | | - return password2 |
100 | | - |
101 | | - def get_password(self): |
102 | | - return self.cleaned_data.get('password1') |
103 | | - |
104 | | - def create_user(self): |
105 | | - user = User.objects.create(username=self.username, |
106 | | - email=self.username) |
107 | | - email = Email.objects.filter(address=self.username) |
108 | | - person = None |
109 | | - if email.count(): |
110 | | - email = email[0] |
111 | | - if email.person: |
112 | | - person = email.person |
113 | | - else: |
114 | | - email = None |
115 | | - if not person: |
116 | | - person = Person.objects.create(user=user, |
117 | | - name=self.username, |
118 | | - ascii=self.username) |
119 | | - if not email: |
120 | | - email = Email.objects.create(address=self.username, |
121 | | - person=person) |
122 | | - email.person = person |
123 | | - email.save() |
124 | | - person.user = user |
125 | | - person.save() |
126 | | - return user |
127 | | - |
128 | | - def get_user(self): |
129 | | - return User.objects.get(username=self.username) |
130 | | - |
131 | | - def save_password_file(self): |
132 | | - if getattr(settings, 'USE_PYTHON_HTDIGEST', None): |
133 | | - pass_file = settings.HTPASSWD_FILE |
134 | | - realm = settings.HTDIGEST_REALM |
135 | | - password = self.get_password() |
136 | | - username = self.username |
137 | | - prefix = '%s:%s:' % (username, realm) |
138 | | - key = hashlib.md5(prefix + password).hexdigest() |
139 | | - f = open(pass_file, 'r+') |
140 | | - pos = f.tell() |
141 | | - line = f.readline() |
142 | | - while line: |
143 | | - if line.startswith(prefix): |
144 | | - break |
145 | | - pos=f.tell() |
146 | | - line = f.readline() |
147 | | - f.seek(pos) |
148 | | - f.write('%s%s\n' % (prefix, key)) |
149 | | - f.close() |
150 | | - else: |
151 | | - p = subprocess.Popen([settings.HTPASSWD_COMMAND, "-b", settings.HTPASSWD_FILE, self.username, self.get_password()], stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
152 | | - stdout, stderr = p.communicate() |
153 | | - |
154 | | - def save(self): |
155 | | - if self.update_user: |
156 | | - user = self.get_user() |
157 | | - else: |
158 | | - user = self.create_user() |
159 | | - user.set_password(self.get_password()) |
160 | | - user.save() |
161 | | - self.save_password_file() |
162 | | - return user |
163 | 94 |
|
164 | 95 | class TestEmailForm(forms.Form): |
165 | 96 | email = forms.EmailField(required=False) |
166 | 97 |
|
167 | | -class PersonForm(ModelForm): |
168 | | - request = None |
169 | | - new_emails = [] |
170 | | - class Meta: |
171 | | - model = Person |
172 | | - exclude = ('time','user') |
173 | | - |
174 | | - def confirm_address(self,email): |
175 | | - person = self.instance |
176 | | - domain = Site.objects.get_current().domain |
177 | | - user = person.user |
178 | | - if len(email) == 0: |
179 | | - return |
180 | | - subject = 'Confirm email address for %s' % person.name |
181 | | - from_email = settings.DEFAULT_FROM_EMAIL |
182 | | - to_email = email |
183 | | - today = datetime.date.today().strftime('%Y%m%d') |
184 | | - auth = hashlib.md5('%s%s%s%s' % (settings.SECRET_KEY, today, to_email, user)).hexdigest() |
185 | | - context = { |
186 | | - 'today': today, |
187 | | - 'domain': domain, |
188 | | - 'user': user, |
189 | | - 'email': email, |
190 | | - 'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK, |
191 | | - 'auth': auth, |
192 | | - } |
193 | | - send_mail(self.request, to_email, from_email, subject, 'registration/add_email_email.txt', context) |
194 | | - |
195 | | - def save(self, force_insert=False, force_update=False, commit=True): |
196 | | - m = super(PersonForm, self).save(commit=False) |
197 | | - self.new_emails = [v for k,v in self.data.items() if k[:10] == u'new_email_' and u'@' in v] |
198 | | - |
199 | | - for email in self.new_emails: |
200 | | - self.confirm_address(email) |
201 | | - |
202 | | - # Process email active flags |
203 | | - emails = Email.objects.filter(person=self.instance) |
204 | | - for email in emails: |
205 | | - email.active = self.data.__contains__(email.address) |
206 | | - if commit: |
207 | | - email.save() |
208 | | - |
209 | | - # Process email for roles |
210 | | - for k,v in self.data.items(): |
211 | | - if k[:11] == u'role_email_': |
212 | | - role = Role.objects.get(id=k[11:]) |
213 | | - email = Email.objects.get(address = v) |
214 | | - role.email = email |
215 | | - if commit: |
216 | | - role.save() |
217 | | - |
218 | | - # Make sure the alias table contains any new and/or old names. |
219 | | - old_names = set([x.name for x in Alias.objects.filter(person=self.instance)]) |
220 | | - curr_names = set([x for x in [self.instance.name, |
221 | | - self.instance.ascii, |
222 | | - self.instance.ascii_short, |
223 | | - self.data['name'], |
224 | | - self.data['ascii'], |
225 | | - self.data['ascii_short']] if len(x)]) |
226 | | - new_names = curr_names - old_names |
227 | | - for name in new_names: |
228 | | - alias = Alias(person=self.instance,name=name) |
229 | | - if commit: |
230 | | - alias.save() |
231 | | - |
232 | | - if commit: |
233 | | - m.save() |
234 | | - return m |
235 | | - |
0 commit comments