From a722e039fc7abee75996969239a4b9ff06c335d4 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Thu, 29 Dec 2011 15:45:45 -0300 Subject: added extra user name validation to make it slugification safe --- askbot/tests/form_tests.py | 1 + askbot/utils/forms.py | 48 ++++++++++++++++++++++++++++++++-------------- askbot/utils/slug.py | 5 +++-- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/askbot/tests/form_tests.py b/askbot/tests/form_tests.py index 2fa572e5..5235b13a 100644 --- a/askbot/tests/form_tests.py +++ b/askbot/tests/form_tests.py @@ -303,5 +303,6 @@ class UserNameFieldTest(AskbotTestCase): #invalid username and username in reserved words self.assertRaises(django_forms.ValidationError, self.username_field.clean, ' ') self.assertRaises(django_forms.ValidationError, self.username_field.clean, 'fuck') + self.assertRaises(django_forms.ValidationError, self.username_field.clean, '......') #TODO: test more things diff --git a/askbot/utils/forms.py b/askbot/utils/forms.py index c3bccf24..536d06b5 100644 --- a/askbot/utils/forms.py +++ b/askbot/utils/forms.py @@ -1,11 +1,12 @@ -from django import forms import re +from django import forms +from django.http import str_to_unicode +from django.contrib.auth.models import User +from django.conf import settings from django.utils.translation import ugettext as _ from django.utils.safestring import mark_safe -from django.conf import settings from askbot.conf import settings as askbot_settings -from django.http import str_to_unicode -from django.contrib.auth.models import User +from askbot.utils.slug import slugify from askbot import const import logging import urllib @@ -26,7 +27,7 @@ def get_next_url(request, default = None): return clean_next(request.REQUEST.get('next'), default) class StrippedNonEmptyCharField(forms.CharField): - def clean(self,value): + def clean(self, value): value = value.strip() if self.required and value == '': raise forms.ValidationError(_('this field is required')) @@ -34,7 +35,14 @@ class StrippedNonEmptyCharField(forms.CharField): class NextUrlField(forms.CharField): def __init__(self): - super(NextUrlField,self).__init__(max_length = 255,widget = forms.HiddenInput(),required = False) + super( + NextUrlField, + self + ).__init__( + max_length = 255, + widget = forms.HiddenInput(), + required = False + ) def clean(self,value): return clean_next(value) @@ -43,19 +51,29 @@ login_form_widget_attrs = { 'class': 'required login' } class UserNameField(StrippedNonEmptyCharField): RESERVED_NAMES = (u'fuck', u'shit', u'ass', u'sex', u'add', u'edit', u'save', u'delete', u'manage', u'update', 'remove', 'new') - def __init__(self,db_model=User, db_field='username', must_exist=False,skip_clean=False,label=_('choose a username'),**kw): + def __init__( + self, + db_model=User, + db_field='username', + must_exist=False, + skip_clean=False, + label=_('choose a username'), + **kw + ): self.must_exist = must_exist self.skip_clean = skip_clean self.db_model = db_model self.db_field = db_field self.user_instance = None - error_messages={'required':_('user name is required'), - 'taken':_('sorry, this name is taken, please choose another'), - 'forbidden':_('sorry, this name is not allowed, please choose another'), - 'missing':_('sorry, there is no user with this name'), - 'multiple-taken':_('sorry, we have a serious error - user name is taken by several users'), - 'invalid':_('user name can only consist of letters, empty space and underscore'), - } + error_messages={ + 'required': _('user name is required'), + 'taken': _('sorry, this name is taken, please choose another'), + 'forbidden': _('sorry, this name is not allowed, please choose another'), + 'missing': _('sorry, there is no user with this name'), + 'multiple-taken': _('sorry, we have a serious error - user name is taken by several users'), + 'invalid': _('user name can only consist of letters, empty space and underscore'), + 'meaningless': _('please use at least some alphabetic characters in the user name'), + } if 'error_messages' in kw: error_messages.update(kw['error_messages']) del kw['error_messages'] @@ -90,6 +108,8 @@ class UserNameField(StrippedNonEmptyCharField): raise forms.ValidationError(self.error_messages['invalid']) if username in self.RESERVED_NAMES: raise forms.ValidationError(self.error_messages['forbidden']) + if slugify(username, force_unidecode = True) == '': + raise forms.ValidationError(self.error_messages['meaningless']) try: user = self.db_model.objects.get( **{'%s' % self.db_field : username} diff --git a/askbot/utils/slug.py b/askbot/utils/slug.py index 1c8010c8..58f228da 100644 --- a/askbot/utils/slug.py +++ b/askbot/utils/slug.py @@ -10,11 +10,12 @@ from django.template import defaultfilters from django.conf import settings import re -def slugify(input_text, max_length=50): +def slugify(input_text, max_length=50, force_unidecode = False): """custom slugify function that removes diacritic modifiers from the characters """ - if getattr(settings, 'ALLOW_UNICODE_SLUGS', False) == False: + allow_unicode_slugs = getattr(settings, 'ALLOW_UNICODE_SLUGS', False) + if allow_unicode_slugs == False or force_unidecode == True: if input_text == '': return input_text slug = defaultfilters.slugify(unidecode(input_text)) -- cgit v1.2.3-1-g7c22