Browse Source

Refractored users validation, made username lenght easily changeable from ACP #49

Ralfp 12 years ago
parent
commit
2cd0c97432

+ 32 - 17
misago/register/fixtures.py

@@ -23,26 +23,20 @@ settings_fixtures = (
                 'name':         _("Default Timezone"),
                 'name':         _("Default Timezone"),
                 'description':  _("Used by guests, crawlers and newly registered users."),
                 'description':  _("Used by guests, crawlers and newly registered users."),
             }),
             }),
-            ('subscribe_start', {
-                'value':        2,
+            ('username_length_min', {
+                'value':        3,
                 'type':         "integer",
                 'type':         "integer",
-                'input':        "select",
-                'extra':        {'choices': ((0, _("Don't watch")),
-                                             (1, _("Put on watched threads list")),
-                                             (2, _("Put on watched threads list and e-mail user when somebody replies")),
-                                             )},
-                'separator':    _("Default Watching Preferences"),
-                'name':         _("Watch threads user started"),
+                'input':        "text",
+                'extra':        {'min': 3},
+                'separator':    _("Users Names"),
+                'name':         _("Minimum allowed username length"),
             }),
             }),
-            ('subscribe_reply', {
-                'value':        2,
+            ('username_length_max', {
+                'value':        16,
                 'type':         "integer",
                 'type':         "integer",
-                'input':        "select",
-                'extra':        {'choices': ((0, _("Don't watch")),
-                                             (1, _("Put on watched threads list")),
-                                             (2, _("Put on watched threads list and e-mail user when somebody replies")),
-                                             )},
-                'name':         _("Watch threads user replied in"),
+                'input':        "text",
+                'extra':        {'min': 3},
+                'name':         _("Maxim allowed username length"),
             }),
             }),
             ('password_length', {
             ('password_length', {
                 'value':        4,
                 'value':        4,
@@ -74,6 +68,27 @@ settings_fixtures = (
                 'name':         _("Include User Password in Welcoming E-mail"),
                 'name':         _("Include User Password in Welcoming E-mail"),
                 'description':  _("If you want to, Misago can include new user password in welcoming e-mail that is sent to new users after successful account creation."),
                 'description':  _("If you want to, Misago can include new user password in welcoming e-mail that is sent to new users after successful account creation."),
             }),
             }),
+            ('subscribe_start', {
+                'value':        2,
+                'type':         "integer",
+                'input':        "select",
+                'extra':        {'choices': ((0, _("Don't watch")),
+                                             (1, _("Put on watched threads list")),
+                                             (2, _("Put on watched threads list and e-mail user when somebody replies")),
+                                             )},
+                'separator':    _("Default Watching Preferences"),
+                'name':         _("Watch threads user started"),
+            }),
+            ('subscribe_reply', {
+                'value':        2,
+                'type':         "integer",
+                'input':        "select",
+                'extra':        {'choices': ((0, _("Don't watch")),
+                                             (1, _("Put on watched threads list")),
+                                             (2, _("Put on watched threads list and e-mail user when somebody replies")),
+                                             )},
+                'name':         _("Watch threads user replied in"),
+            }),
         ),
         ),
     }),
     }),
 )
 )

+ 3 - 3
misago/register/forms.py

@@ -30,7 +30,7 @@ class UserRegisterForm(Form):
         self.layout = [
         self.layout = [
                       (
                       (
                        None,
                        None,
-                       [('username', {'label': _('Username'), 'help_text': _("Your displayed username. Between 3 and 15 characters, only letters and digits are allowed."),'attrs': {'placeholder': _("Enter your desired username")}})]
+                       [('username', {'label': _('Username'), 'help_text': _("Your displayed username. Between %(min)s and %(max)s characters, only letters and digits are allowed.") % {'min': self.request.settings['username_length_min'], 'max': self.request.settings['username_length_max']},'attrs': {'placeholder': _("Enter your desired username")}})]
                        ),
                        ),
                       (
                       (
                        None,
                        None,
@@ -52,7 +52,7 @@ class UserRegisterForm(Form):
             del self.layout[3]
             del self.layout[3]
         
         
     def clean_username(self):
     def clean_username(self):
-        validate_username(self.cleaned_data['username'])
+        validate_username(self.cleaned_data['username'], self.request.settings)
         new_user = User.objects.get_blank_user()
         new_user = User.objects.get_blank_user()
         new_user.set_username(self.cleaned_data['username'])
         new_user.set_username(self.cleaned_data['username'])
         try:
         try:
@@ -71,11 +71,11 @@ class UserRegisterForm(Form):
         return self.cleaned_data['email']
         return self.cleaned_data['email']
         
         
     def clean_password(self):
     def clean_password(self):
+        validate_password(self.cleaned_data['password'], self.request.settings)
         new_user = User.objects.get_blank_user()
         new_user = User.objects.get_blank_user()
         new_user.set_password(self.cleaned_data['password'])
         new_user.set_password(self.cleaned_data['password'])
         try:
         try:
             new_user.full_clean()
             new_user.full_clean()
         except ValidationError as e:
         except ValidationError as e:
             new_user.is_password_valid(e)
             new_user.is_password_valid(e)
-        validate_password(self.cleaned_data['password'])
         return self.cleaned_data['password']
         return self.cleaned_data['password']

+ 1 - 1
misago/usercp/username/forms.py

@@ -21,7 +21,7 @@ class UsernameChangeForm(Form):
         org_username = self.request.user.username
         org_username = self.request.user.username
         if org_username == self.cleaned_data['username']:
         if org_username == self.cleaned_data['username']:
             raise ValidationError(_("Your new username is same as current one."))
             raise ValidationError(_("Your new username is same as current one."))
-        validate_username(self.cleaned_data['username'])
+        validate_username(self.cleaned_data['username'], self.request.settings)
         self.request.user.set_username(self.cleaned_data['username'])
         self.request.user.set_username(self.cleaned_data['username'])
         try:
         try:
             self.request.user.full_clean()
             self.request.user.full_clean()

+ 191 - 191
misago/users/forms.py

@@ -10,200 +10,200 @@ from misago.users.validators import validate_username, validate_password, valida
 from misago.forms import Form, YesNoSwitch
 from misago.forms import Form, YesNoSwitch
 
 
 class UserForm(Form):
 class UserForm(Form):
-		username = forms.CharField(max_length=255)
-		title = forms.CharField(max_length=255, required=False)
-		rank = forms.ModelChoiceField(queryset=Rank.objects.order_by('order').all(), required=False, empty_label=_('No rank assigned'))
-		roles = False
-		email = forms.EmailField(max_length=255)
-		new_password = forms.CharField(max_length=255, required=False, widget=forms.PasswordInput)
-		signature = forms.CharField(widget=forms.Textarea, required=False)
-		avatar_custom = forms.CharField(max_length=255, required=False)
-		avatar_ban = forms.BooleanField(widget=YesNoSwitch, required=False)
-		avatar_ban_reason_user = forms.CharField(widget=forms.Textarea, required=False)
-		avatar_ban_reason_admin = forms.CharField(widget=forms.Textarea, required=False)
-		signature_ban = forms.BooleanField(widget=YesNoSwitch, required=False)
-		signature_ban_reason_user = forms.CharField(widget=forms.Textarea, required=False)
-		signature_ban_reason_admin = forms.CharField(widget=forms.Textarea, required=False)
-
-		def __init__(self, user=None, *args, **kwargs):
-				self.request = kwargs['request']
-				self.user = user
-				super(UserForm, self).__init__(*args, **kwargs)
-
-		def finalize_form(self):
-				self.layout = [
-											 [
-												_("Basic Account Settings"),
-												[
-												 ('username', {'label': _("Username"), 'help_text': _("Username is name under which user is known to other users. Between 3 and 15 characters, only letters and digits are allowed.")}),
-												 ('title', {'label': _("User Title"), 'help_text': _("To override user title with custom one, enter it here.")}),
-												 ('rank', {'label': _("User Rank"), 'help_text': _("This user rank.")}),
-												 ('roles', {'label': _("User Roles"), 'help_text': _("This user roles. Roles are sets of user permissions")}),
-												 ],
-												],
-											 [
-												_("Sign-in Credentials"),
-												[
-												 ('email', {'label': _("E-mail Address"), 'help_text': _("Member e-mail address.")}),
-												 ('new_password', {'label': _("Change User Password"), 'help_text': _("If you wish to change user password, enter here new password. Otherwhise leave this field blank."), 'has_value': False}),
-												 ],
-												],
-											 [
-												_("User Avatar"),
-												[
-												 ('avatar_custom', {'label': _("Set Non-Standard Avatar"), 'help_text': _("You can make this member use special avatar by entering name of image file located in avatars directory here.")}),
-												 ('avatar_ban', {'label': _("Lock Member's Avatar"), 'help_text': _("If you set this field to yes, this member's avatar will be deleted and replaced with random one selected from _removed gallery and member will not be able to change his avatar.")}),
-												 ('avatar_ban_reason_user', {'label': _("User-visible reason for lock"), 'help_text': _("You can leave message to member explaining why he or she is unable to change his avatar anymore. This message will be displayed to member in his control panel.")}),
-												 ('avatar_ban_reason_admin', {'label': _("Forum Team-visible reason for lock"), 'help_text': _("You can leave message to other forum team members exmplaining why this member's avatar has been locked.")}),
-												 ],
-												],
-											 [
-												_("User Signature"),
-												[
-												 ('signature', {'label': _("Signature"), 'help_text': _("Signature is short message attached at end of member's messages.")}),
-												 ('signature_ban', {'label': _("Lock Member's Signature"), 'help_text': _("If you set this field to yes, this member will not be able to change his signature.")}),
-												 ('signature_ban_reason_user', {'label': _("User-visible reason for lock"), 'help_text': _("You can leave message to member explaining why he or she is unable to edit his signature anymore. This message will be displayed to member in his control panel.")}),
-												 ('signature_ban_reason_admin', {'label': _("Forum Team-visible reason for lock"), 'help_text': _("You can leave message to other forum team members exmplaining why this member's signature has been locked.")}),
-												 ],
-												],
-											 ]
-
-				# Roles list
-				if self.request.user.is_god():
-						self.fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), error_messages={'required': _("User must have at least one role assigned.")})
-				else:
-						self.fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.filter(protected__exact=False).order_by('name').all(), required=False)
-
-				# Keep non-gods from editing protected members sign-in credentials
-				if self.user.is_protected() and not self.request.user.is_god() and self.user.pk != self.request.user.pk:
-						del self.fields['email']
-						del self.fields['new_password']
-						del self.layout[1]
-
-		def clean_username(self):
-				org_username = self.user.username
-				validate_username(self.cleaned_data['username'])
-				self.user.set_username(self.cleaned_data['username'])
-				try:
-						self.user.full_clean()
-				except ValidationError as e:
-						self.user.is_username_valid(e)
-						self.user.set_username(org_username)
-				return self.cleaned_data['username']
-
-		def clean_email(self):
-				self.user.set_email(self.cleaned_data['email'])
-				try:
-						self.user.full_clean()
-				except ValidationError as e:
-						self.user.is_email_valid(e)
-				return self.cleaned_data['email']
-
-		def clean_new_password(self):
-				if self.cleaned_data['new_password']:
-						self.user.set_password(self.cleaned_data['new_password'])
-						try:
-								self.user.full_clean()
-						except ValidationError as e:
-								self.user.is_password_valid(e)
-						validate_password(self.cleaned_data['new_password'])
-						return self.cleaned_data['new_password']
-				return ''
-
-		def clean_avatar_custom(self):
-				if self.cleaned_data['avatar_custom']:
-						try:
-								avatar_image = Image.open('%s/avatars/%s' % (settings.STATICFILES_DIRS[0], self.cleaned_data['avatar_custom']))
-						except IOError:
-								raise ValidationError(_("Avatar does not exist or is not image file."))
-						return self.cleaned_data['avatar_custom']
-				return ''
+    username = forms.CharField(max_length=255)
+    title = forms.CharField(max_length=255, required=False)
+    rank = forms.ModelChoiceField(queryset=Rank.objects.order_by('order').all(), required=False, empty_label=_('No rank assigned'))
+    roles = False
+    email = forms.EmailField(max_length=255)
+    new_password = forms.CharField(max_length=255, required=False, widget=forms.PasswordInput)
+    signature = forms.CharField(widget=forms.Textarea, required=False)
+    avatar_custom = forms.CharField(max_length=255, required=False)
+    avatar_ban = forms.BooleanField(widget=YesNoSwitch, required=False)
+    avatar_ban_reason_user = forms.CharField(widget=forms.Textarea, required=False)
+    avatar_ban_reason_admin = forms.CharField(widget=forms.Textarea, required=False)
+    signature_ban = forms.BooleanField(widget=YesNoSwitch, required=False)
+    signature_ban_reason_user = forms.CharField(widget=forms.Textarea, required=False)
+    signature_ban_reason_admin = forms.CharField(widget=forms.Textarea, required=False)
+
+    def __init__(self, user=None, *args, **kwargs):
+        self.request = kwargs['request']
+        self.user = user
+        super(UserForm, self).__init__(*args, **kwargs)
+
+    def finalize_form(self):
+        self.layout = [
+                       [
+                        _("Basic Account Settings"),
+                        [
+                         ('username', {'label': _("Username"), 'help_text': _("Username is name under which user is known to other users. Between 3 and 15 characters, only letters and digits are allowed.")}),
+                         ('title', {'label': _("User Title"), 'help_text': _("To override user title with custom one, enter it here.")}),
+                         ('rank', {'label': _("User Rank"), 'help_text': _("This user rank.")}),
+                         ('roles', {'label': _("User Roles"), 'help_text': _("This user roles. Roles are sets of user permissions")}),
+                         ],
+                        ],
+                       [
+                        _("Sign-in Credentials"),
+                        [
+                         ('email', {'label': _("E-mail Address"), 'help_text': _("Member e-mail address.")}),
+                         ('new_password', {'label': _("Change User Password"), 'help_text': _("If you wish to change user password, enter here new password. Otherwhise leave this field blank."), 'has_value': False}),
+                         ],
+                        ],
+                       [
+                        _("User Avatar"),
+                        [
+                         ('avatar_custom', {'label': _("Set Non-Standard Avatar"), 'help_text': _("You can make this member use special avatar by entering name of image file located in avatars directory here.")}),
+                         ('avatar_ban', {'label': _("Lock Member's Avatar"), 'help_text': _("If you set this field to yes, this member's avatar will be deleted and replaced with random one selected from _removed gallery and member will not be able to change his avatar.")}),
+                         ('avatar_ban_reason_user', {'label': _("User-visible reason for lock"), 'help_text': _("You can leave message to member explaining why he or she is unable to change his avatar anymore. This message will be displayed to member in his control panel.")}),
+                         ('avatar_ban_reason_admin', {'label': _("Forum Team-visible reason for lock"), 'help_text': _("You can leave message to other forum team members exmplaining why this member's avatar has been locked.")}),
+                         ],
+                        ],
+                       [
+                        _("User Signature"),
+                        [
+                         ('signature', {'label': _("Signature"), 'help_text': _("Signature is short message attached at end of member's messages.")}),
+                         ('signature_ban', {'label': _("Lock Member's Signature"), 'help_text': _("If you set this field to yes, this member will not be able to change his signature.")}),
+                         ('signature_ban_reason_user', {'label': _("User-visible reason for lock"), 'help_text': _("You can leave message to member explaining why he or she is unable to edit his signature anymore. This message will be displayed to member in his control panel.")}),
+                         ('signature_ban_reason_admin', {'label': _("Forum Team-visible reason for lock"), 'help_text': _("You can leave message to other forum team members exmplaining why this member's signature has been locked.")}),
+                         ],
+                        ],
+                       ]
+
+        # Roles list
+        if self.request.user.is_god():
+            self.fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), error_messages={'required': _("User must have at least one role assigned.")})
+        else:
+            self.fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.filter(protected__exact=False).order_by('name').all(), required=False)
+
+        # Keep non-gods from editing protected members sign-in credentials
+        if self.user.is_protected() and not self.request.user.is_god() and self.user.pk != self.request.user.pk:
+            del self.fields['email']
+            del self.fields['new_password']
+            del self.layout[1]
+
+    def clean_username(self):
+        org_username = self.user.username
+        validate_username(self.cleaned_data['username'], self.request.settings)
+        self.user.set_username(self.cleaned_data['username'])
+        try:
+            self.user.full_clean()
+        except ValidationError as e:
+            self.user.is_username_valid(e)
+            self.user.set_username(org_username)
+        return self.cleaned_data['username']
+
+    def clean_email(self):
+        self.user.set_email(self.cleaned_data['email'])
+        try:
+            self.user.full_clean()
+        except ValidationError as e:
+            self.user.is_email_valid(e)
+        return self.cleaned_data['email']
+
+    def clean_new_password(self):
+        if self.cleaned_data['new_password']:
+            validate_password(self.cleaned_data['new_password'], self.request.settings)
+            self.user.set_password(self.cleaned_data['new_password'])
+            try:
+                self.user.full_clean()
+            except ValidationError as e:
+                self.user.is_password_valid(e)
+            return self.cleaned_data['new_password']
+        return ''
+
+    def clean_avatar_custom(self):
+        if self.cleaned_data['avatar_custom']:
+            try:
+                avatar_image = Image.open('%s/avatars/%s' % (settings.STATICFILES_DIRS[0], self.cleaned_data['avatar_custom']))
+            except IOError:
+                raise ValidationError(_("Avatar does not exist or is not image file."))
+            return self.cleaned_data['avatar_custom']
+        return ''
 
 
 
 
 class NewUserForm(Form):
 class NewUserForm(Form):
-		username = forms.CharField(max_length=255)
-		title = forms.CharField(max_length=255, required=False)
-		rank = forms.ModelChoiceField(queryset=Rank.objects.order_by('order').all(), required=False, empty_label=_('No rank assigned'))
-		roles = False
-		email = forms.EmailField(max_length=255)
-		password = forms.CharField(max_length=255, widget=forms.PasswordInput)
-
-		layout = [
-							[
-							 _("Basic Account Settings"),
-							 [
-								('username', {'label': _("Username"), 'help_text': _("Username is name under which user is known to other users. Between 3 and 15 characters, only letters and digits are allowed.")}),
-								('title', {'label': _("User Title"), 'help_text': _("To override user title with custom one, enter it here.")}),
-								('rank', {'label': _("User Rank"), 'help_text': _("This user rank.")}),
-								('roles', {'label': _("User Roles"), 'help_text': _("This user roles. Roles are sets of user permissions")}),
-								],
-							 ],
-							[
-							 _("Sign-in Credentials"),
-							 [
-								('email', {'label': _("E-mail Address"), 'help_text': _("Member e-mail address.")}),
-								('password', {'label': _("User Password"), 'help_text': _("Member password."), 'has_value': False}),
-								],
-							 ],
-							]
-
-		def __init__(self, *args, **kwargs):
-				self.request = kwargs['request']
-
-				# Roles list
-				if self.request.user.is_god():
-						self.base_fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), error_messages={'required': _("User must have at least one role assigned.")})
-				else:
-						self.base_fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.filter(protected__exact=False).order_by('name').all(), required=False)
-
-				super(NewUserForm, self).__init__(*args, **kwargs)
-
-		def clean_username(self):
-				validate_username(self.cleaned_data['username'])
-				new_user = User.objects.get_blank_user()
-				new_user.set_username(self.cleaned_data['username'])
-				try:
-						new_user.full_clean()
-				except ValidationError as e:
-						new_user.is_username_valid(e)
-				return self.cleaned_data['username']
-
-		def clean_email(self):
-				new_user = User.objects.get_blank_user()
-				new_user.set_email(self.cleaned_data['email'])
-				try:
-						new_user.full_clean()
-				except ValidationError as e:
-						new_user.is_email_valid(e)
-				return self.cleaned_data['email']
-
-		def clean_password(self):
-				new_user = User.objects.get_blank_user()
-				new_user.set_password(self.cleaned_data['password'])
-				try:
-						new_user.full_clean()
-				except ValidationError as e:
-						new_user.is_password_valid(e)
-				validate_password(self.cleaned_data['password'])
-				return self.cleaned_data['password']
+    username = forms.CharField(max_length=255)
+    title = forms.CharField(max_length=255, required=False)
+    rank = forms.ModelChoiceField(queryset=Rank.objects.order_by('order').all(), required=False, empty_label=_('No rank assigned'))
+    roles = False
+    email = forms.EmailField(max_length=255)
+    password = forms.CharField(max_length=255, widget=forms.PasswordInput)
+
+    layout = [
+              [
+               _("Basic Account Settings"),
+               [
+                ('username', {'label': _("Username"), 'help_text': _("Username is name under which user is known to other users. Between 3 and 15 characters, only letters and digits are allowed.")}),
+                ('title', {'label': _("User Title"), 'help_text': _("To override user title with custom one, enter it here.")}),
+                ('rank', {'label': _("User Rank"), 'help_text': _("This user rank.")}),
+                ('roles', {'label': _("User Roles"), 'help_text': _("This user roles. Roles are sets of user permissions")}),
+                ],
+               ],
+              [
+               _("Sign-in Credentials"),
+               [
+                ('email', {'label': _("E-mail Address"), 'help_text': _("Member e-mail address.")}),
+                ('password', {'label': _("User Password"), 'help_text': _("Member password."), 'has_value': False}),
+                ],
+               ],
+              ]
+
+    def __init__(self, *args, **kwargs):
+            self.request = kwargs['request']
+
+            # Roles list
+            if self.request.user.is_god():
+                    self.base_fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), error_messages={'required': _("User must have at least one role assigned.")})
+            else:
+                    self.base_fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.filter(protected__exact=False).order_by('name').all(), required=False)
+
+            super(NewUserForm, self).__init__(*args, **kwargs)
+
+    def clean_username(self):
+            validate_username(self.cleaned_data['username'])
+            new_user = User.objects.get_blank_user()
+            new_user.set_username(self.cleaned_data['username'])
+            try:
+                    new_user.full_clean()
+            except ValidationError as e:
+                    new_user.is_username_valid(e)
+            return self.cleaned_data['username']
+
+    def clean_email(self):
+            new_user = User.objects.get_blank_user()
+            new_user.set_email(self.cleaned_data['email'])
+            try:
+                    new_user.full_clean()
+            except ValidationError as e:
+                    new_user.is_email_valid(e)
+            return self.cleaned_data['email']
+
+    def clean_password(self):
+            new_user = User.objects.get_blank_user()
+            new_user.set_password(self.cleaned_data['password'])
+            try:
+                    new_user.full_clean()
+            except ValidationError as e:
+                    new_user.is_password_valid(e)
+            validate_password(self.cleaned_data['password'])
+            return self.cleaned_data['password']
 
 
 
 
 class SearchUsersForm(Form):
 class SearchUsersForm(Form):
-		username = forms.CharField(max_length=255, required=False)
-		email = forms.CharField(max_length=255, required=False)
-		activation = forms.TypedMultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=((0, _("Already Active")), (1, _("By User")), (2, _("By Administrator"))), coerce=int, required=False)
-		rank = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Rank.objects.order_by('order').all(), required=False)
-		role = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), required=False)
-
-		layout = (
-							(
-							 _("Search Users"),
-							 (
-								('username', {'label': _("Username"), 'attrs': {'placeholder': _("Username contains...")}}),
-								('email', {'label': _("E-mail Address"), 'attrs': {'placeholder': _("E-mail address contains...")}}),
-								('activation', {'label': _("Activation Requirement")}),
-								('rank', {'label': _("Rank is")}),
-								('role', {'label': _("Has Role")}),
-							 ),
-							),
-						 )
+    username = forms.CharField(max_length=255, required=False)
+    email = forms.CharField(max_length=255, required=False)
+    activation = forms.TypedMultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=((0, _("Already Active")), (1, _("By User")), (2, _("By Administrator"))), coerce=int, required=False)
+    rank = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Rank.objects.order_by('order').all(), required=False)
+    role = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), required=False)
+
+    layout = (
+            (
+             _("Search Users"),
+             (
+                ('username', {'label': _("Username"), 'attrs': {'placeholder': _("Username contains...")}}),
+                ('email', {'label': _("E-mail Address"), 'attrs': {'placeholder': _("E-mail address contains...")}}),
+                ('activation', {'label': _("Activation Requirement")}),
+                ('rank', {'label': _("Rank is")}),
+                ('role', {'label': _("Has Role")}),
+             ),
+                ),
+             )

+ 3 - 1
misago/users/models.py

@@ -74,6 +74,8 @@ class UserManager(models.Manager):
                         subscribe_reply=db_settings['subscribe_reply'],
                         subscribe_reply=db_settings['subscribe_reply'],
                         )
                         )
 
 
+        validate_username(username, db_settings)
+        validate_password(password, db_settings)
         new_user.set_username(username)
         new_user.set_username(username)
         new_user.set_email(email)
         new_user.set_email(email)
         new_user.set_password(password)
         new_user.set_password(password)
@@ -117,7 +119,7 @@ class User(models.Model):
     """
     """
     Misago User model
     Misago User model
     """
     """
-    username = models.CharField(max_length=255, validators=[validate_username])
+    username = models.CharField(max_length=255)
     username_slug = models.SlugField(max_length=255, unique=True,
     username_slug = models.SlugField(max_length=255, unique=True,
                                      error_messages={'unique': _("This user name is already in use by another user.")})
                                      error_messages={'unique': _("This user name is already in use by another user.")})
     email = models.EmailField(max_length=255, validators=[validate_email])
     email = models.EmailField(max_length=255, validators=[validate_email])

+ 18 - 7
misago/users/validators.py

@@ -5,12 +5,24 @@ from django.utils.translation import ungettext, ugettext_lazy as _
 from misago.banning.models import check_ban
 from misago.banning.models import check_ban
 from misago.settings.settings import Settings as DBSettings
 from misago.settings.settings import Settings as DBSettings
 
 
-def validate_username(value):
+def validate_username(value, db_settings):
     value = unicode(value).strip()
     value = unicode(value).strip()
-    if len(value) < 3:
-        raise ValidationError(_("Username cannot be shorter than 3 characters."))
-    if len(value) > 12:
-        raise ValidationError(_("Username cannot be longer than 12 characters."))
+    if len(value) < db_settings['username_length_min']:
+        raise ValidationError(ungettext(
+            'Username must be at least one character long.',
+            'Username must be at least %(count)d characters long.',
+            db_settings['username_length_min']
+        ) % {
+            'count': db_settings['username_length_min'],
+        })
+    if len(value) > db_settings['username_length_max']:
+        raise ValidationError(ungettext(
+            'Username cannot be longer than one characters.',
+            'Username cannot be longer than %(count)d characters.',
+            db_settings['username_length_max']
+        ) % {
+            'count': db_settings['username_length_max'],
+        })
     if settings.UNICODE_USERNAMES:
     if settings.UNICODE_USERNAMES:
         if not re.search('^[^\W_]+$', value, re.UNICODE):
         if not re.search('^[^\W_]+$', value, re.UNICODE):
             raise ValidationError(_("Username can only contain letters and digits."))
             raise ValidationError(_("Username can only contain letters and digits."))
@@ -21,9 +33,8 @@ def validate_username(value):
         raise ValidationError(_("This username is forbidden."))
         raise ValidationError(_("This username is forbidden."))
 
 
 
 
-def validate_password(value):
+def validate_password(value, db_settings):
     value = unicode(value).strip()
     value = unicode(value).strip()
-    db_settings = DBSettings()
     if len(value) < db_settings['password_length']:
     if len(value) < db_settings['password_length']:
         raise ValidationError(ungettext(
         raise ValidationError(ungettext(
             'Correct password has to be at least one character long.',
             'Correct password has to be at least one character long.',