import re from django import forms from django.conf import settings from django.core.exceptions import ValidationError from django.forms import ModelForm from django.db import models from django.contrib.auth.models import User from django.utils.html import mark_safe from django.core.urlresolvers import reverse as urlreverse from unidecode import unidecode import debug # pyflakes:ignore from ietf.person.models import Person, Email from ietf.mailinglists.models import Whitelisted class RegistrationForm(forms.Form): email = forms.EmailField(label="Your email (lowercase)") def clean_email(self): email = self.cleaned_data.get('email', '') if not email: return email if email.lower() != email: raise forms.ValidationError('The supplied address contained uppercase letters. Please use a lowercase email address.') if User.objects.filter(username=email).exists(): raise forms.ValidationError('An account with the email address you provided already exists.') return email class PasswordForm(forms.Form): password = forms.CharField(widget=forms.PasswordInput) password_confirmation = forms.CharField(widget=forms.PasswordInput, help_text="Enter the same password as above, for verification.") def clean_password_confirmation(self): password = self.cleaned_data.get("password", "") password_confirmation = self.cleaned_data["password_confirmation"] if password != password_confirmation: raise forms.ValidationError("The two password fields didn't match.") return password_confirmation def ascii_cleaner(supposedly_ascii): outside_printable_ascii_pattern = r'[^\x20-\x7F]' if re.search(outside_printable_ascii_pattern, supposedly_ascii): raise forms.ValidationError("Only unaccented Latin characters are allowed.") return supposedly_ascii def prevent_at_symbol(name): if "@" in name: raise forms.ValidationError("Please fill in name - this looks like an email address (@ is not allowed in names).") def prevent_system_name(name): name_without_spaces = name.replace(" ", "").replace("\t", "") if "(system)" in name_without_spaces.lower(): raise forms.ValidationError("Please pick another name - this name is reserved.") def get_person_form(*args, **kwargs): exclude_list = ['time', 'user', 'photo_thumb', 'photo', ] person = kwargs['instance'] roles = person.role_set.all() if not roles: exclude_list += ['biography', 'photo', ] class PersonForm(ModelForm): class Meta: model = Person exclude = exclude_list def __init__(self, *args, **kwargs): super(PersonForm, self).__init__(*args, **kwargs) # blank ascii if it's the same as name self.fields["ascii"].required = self.fields["ascii"].widget.is_required = False self.fields["ascii"].help_text += " " + "Leave blank to use auto-reconstructed Latin version of name." if self.initial.get("ascii") == self.initial.get("name"): self.initial["ascii"] = "" self.unidecoded_ascii = False if self.data and not self.data.get("ascii", "").strip(): self.data = self.data.copy() name = self.data["name"] reconstructed_name = unidecode(name) self.data["ascii"] = reconstructed_name self.unidecoded_ascii = name != reconstructed_name def clean_name(self): name = self.cleaned_data.get("name") or u"" prevent_at_symbol(name) prevent_system_name(name) return name def clean_ascii(self): if self.unidecoded_ascii: raise forms.ValidationError("Name contained non-ASCII characters, and was automatically reconstructed using only Latin characters. Check the result - if you are happy, just hit Submit again.") name = self.cleaned_data.get("ascii") or u"" prevent_at_symbol(name) prevent_system_name(name) return ascii_cleaner(name) def clean_ascii_short(self): name = self.cleaned_data.get("ascii_short") or u"" prevent_at_symbol(name) prevent_system_name(name) return ascii_cleaner(name) return PersonForm(*args, **kwargs) class NewEmailForm(forms.Form): new_email = forms.EmailField(label="New email address", required=False) def clean_new_email(self): email = self.cleaned_data.get("new_email", "") if email: existing = Email.objects.filter(address=email).first() if existing: raise forms.ValidationError("Email address '%s' is already assigned to account '%s' (%s)" % (existing, existing.person and existing.person.user, existing.person)) for pat in settings.EXLUDED_PERSONAL_EMAIL_REGEX_PATTERNS: if re.search(pat, email): raise ValidationError("This email address is not valid in a datatracker account") return email class RoleEmailForm(forms.Form): email = forms.ModelChoiceField(label="Role email", queryset=Email.objects.all()) def __init__(self, role, *args, **kwargs): super(RoleEmailForm, self).__init__(*args, **kwargs) f = self.fields["email"] f.label = u"%s in %s" % (role.name, role.group.acronym.upper()) f.help_text = u"Email to use for %s role in %s" % (role.name, role.group.name) f.queryset = f.queryset.filter(models.Q(person=role.person_id) | models.Q(role=role)).distinct() f.initial = role.email_id f.choices = [(e.pk, e.address if e.active else u"({})".format(e.address)) for e in f.queryset] class ResetPasswordForm(forms.Form): username = forms.EmailField(label="Your email (lowercase)") def clean_username(self): import ietf.ietfauth.views username = self.cleaned_data["username"] if not User.objects.filter(username=username).exists(): raise forms.ValidationError(mark_safe("Didn't find a matching account. If you don't have an account yet, you can create one.".format(urlreverse(ietf.ietfauth.views.create_account)))) return username class TestEmailForm(forms.Form): email = forms.EmailField(required=False) class WhitelistForm(ModelForm): class Meta: model = Whitelisted exclude = ['by', 'time' ]