[#8337] show more helpful messages when username is wrong format
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 1fde18c..00d6128 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -45,6 +45,7 @@
from tg import tmpl_context as c, app_globals as g
from webob import exc, Request
from paste.deploy.converters import asbool, asint
+from formencode import validators as fev
from ming.utils import LazyProperty
from ming.orm import state
@@ -479,6 +480,17 @@
return False
+ def username_validator(self, long_message=True):
+ validator = fev.Regex(h.re_project_name)
+ if long_message:
+ validator._messages['invalid'] = (
+ 'Usernames must include only small letters, numbers, and dashes.'
+ ' They must also start with a letter and be at least 3 characters'
+ ' long.')
+ else:
+ validator._messages['invalid'] = 'Usernames only include small letters, numbers, and dashes'
+ return validator
+
class LocalAuthenticationProvider(AuthenticationProvider):
diff --git a/Allura/allura/lib/widgets/auth_widgets.py b/Allura/allura/lib/widgets/auth_widgets.py
index 3233015..47c6764 100644
--- a/Allura/allura/lib/widgets/auth_widgets.py
+++ b/Allura/allura/lib/widgets/auth_widgets.py
@@ -21,6 +21,7 @@
from tg import request, tmpl_context as c
from formencode import Invalid
+from formencode import validators as fev
from webob import exc
from .forms import ForgeForm
@@ -69,8 +70,15 @@
@validator
def validate(self, value, state=None):
+ super(LoginForm, self).validate(value, state=state)
+ auth_provider = plugin.AuthenticationProvider.get(request)
+
+ # can't use a validator attr on the username TextField, since the antispam encoded name changes and doesn't
+ # match the name used in the form submission
+ auth_provider.username_validator(long_message=False).to_python(value['username'])
+
try:
- plugin.AuthenticationProvider.get(request).login()
+ auth_provider.login()
except exc.HTTPUnauthorized:
msg = 'Invalid login'
raise Invalid(
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index 68254d9..930b6bc 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -778,12 +778,8 @@
username = ew.TextField(
name='username',
label='Desired Username',
- validator=fev.Regex(
- h.re_project_name))
- username.validator._messages['invalid'] = (
- 'Usernames must include only small letters, numbers, and dashes.'
- ' They must also start with a letter and be at least 3 characters'
- ' long.')
+ validator=plugin.AuthenticationProvider.get(None).username_validator(),
+ )
fields = [
ew.TextField(
name='display_name',
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index b8066b6..a7c6893 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -100,6 +100,16 @@
_session_id=self.app.cookies['_session_id']))
assert 'Invalid login' in str(r), r.showbrowser()
+ def test_login_invalid_username(self):
+ extra = {'username': '*anonymous'}
+ r = self.app.get('/auth/', extra_environ=extra)
+ f = r.forms[0]
+ encoded = self.app.antispam_field_names(f)
+ f[encoded['username']] = 'test@user.com'
+ f[encoded['password']] = 'foo'
+ r = f.submit(extra_environ={'username': '*anonymous'})
+ r.mustcontain('Usernames only include small letters, ')
+
def test_login_diff_ips_ok(self):
# exercises AntiSpam.validate methods
extra = {'username': '*anonymous', 'REMOTE_ADDR': '11.22.33.44'}