From d56560ed897a7343655fced9768795f0523c9ef8 Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Wed, 3 Aug 2016 10:21:02 +0000 Subject: [PATCH 1/3] Throw a validation error if a profile name contains an @ sign upon edit so that people do not forget to enter their name. Commit ready for merge. - Legacy-Id: 11750 --- ietf/ietfauth/forms.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ietf/ietfauth/forms.py b/ietf/ietfauth/forms.py index 179c0fe65..c955fdbe8 100644 --- a/ietf/ietfauth/forms.py +++ b/ietf/ietfauth/forms.py @@ -48,6 +48,10 @@ def ascii_cleaner(supposedly_ascii): raise forms.ValidationError("Please only enter ASCII characters.") 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 get_person_form(*args, **kwargs): exclude_list = ['time', 'user', 'photo_thumb', 'photo', ] @@ -65,11 +69,20 @@ def get_person_form(*args, **kwargs): def __init__(self, *args, **kwargs): super(ModelForm, self).__init__(*args, **kwargs) + def clean_name(self): + name = self.cleaned_data.get("name") or u"" + prevent_at_symbol(name) + return name + def clean_ascii(self): - return ascii_cleaner(self.cleaned_data.get("ascii") or u"") + name = self.cleaned_data.get("ascii") or u"" + prevent_at_symbol(name) + return ascii_cleaner(name) def clean_ascii_short(self): - return ascii_cleaner(self.cleaned_data.get("ascii_short") or u"") + name = self.cleaned_data.get("ascii_short") or u"" + prevent_at_symbol(name) + return ascii_cleaner(name) return PersonForm(*args, **kwargs) From afccaa0b4dfe6ac75b3866e071a077d67236b0fa Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Wed, 3 Aug 2016 14:20:13 +0000 Subject: [PATCH 2/3] Handle Person.ascii in edit profile better to try to ensure that people fill it in correctly. Blank it out if it's unchanged from name and use unidecode to set it automatically (with a warning if it actually converts something). Branch ready for merge. - Legacy-Id: 11752 --- ietf/ietfauth/forms.py | 23 ++++++++++++++++++++++- ietf/ietfauth/tests.py | 9 +++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ietf/ietfauth/forms.py b/ietf/ietfauth/forms.py index c955fdbe8..377442d03 100644 --- a/ietf/ietfauth/forms.py +++ b/ietf/ietfauth/forms.py @@ -9,6 +9,8 @@ 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 @@ -45,7 +47,7 @@ class PasswordForm(forms.Form): def ascii_cleaner(supposedly_ascii): outside_printable_ascii_pattern = r'[^\x20-\x7F]' if re.search(outside_printable_ascii_pattern, supposedly_ascii): - raise forms.ValidationError("Please only enter ASCII characters.") + raise forms.ValidationError("Only unaccented Latin characters are allowed.") return supposedly_ascii def prevent_at_symbol(name): @@ -69,12 +71,31 @@ def get_person_form(*args, **kwargs): def __init__(self, *args, **kwargs): super(ModelForm, 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) 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) return ascii_cleaner(name) diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 39927426f..335a5f489 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -213,6 +213,15 @@ class IetfAuthTests(TestCase): q = PyQuery(r.content) self.assertTrue(len(q("form .has-error")) > 0) + # edit details - blank ASCII + blank_ascii = base_data.copy() + blank_ascii["ascii"] = u"" + r = self.client.post(url, blank_ascii) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(len(q("form .has-error")) > 0) # we get a warning about reconstructed name + self.assertEqual(q("input[name=ascii]").val(), base_data["ascii"]) + # edit details r = self.client.post(url, base_data) self.assertEqual(r.status_code, 200) From c4e2f68ea5eeb653e9848dba2b9e5679b1ba58cd Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Mon, 15 Aug 2016 13:14:08 +0000 Subject: [PATCH 3/3] Add check for reserved name in account registration Commit ready for merge - Legacy-Id: 11783 --- ietf/ietfauth/forms.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ietf/ietfauth/forms.py b/ietf/ietfauth/forms.py index 377442d03..9779fd218 100644 --- a/ietf/ietfauth/forms.py +++ b/ietf/ietfauth/forms.py @@ -54,6 +54,11 @@ 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', ] @@ -90,6 +95,7 @@ def get_person_form(*args, **kwargs): 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): @@ -98,11 +104,13 @@ def get_person_form(*args, **kwargs): 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)