Fixes #765. Avoids the django AbstracUser username validator
Also changed added a white-space in the default username again
This commit is contained in:
parent
0e29200bac
commit
7d1eb5207a
@ -23,7 +23,7 @@ from openslides.participant.models import User, Group
|
|||||||
|
|
||||||
def gen_password():
|
def gen_password():
|
||||||
"""
|
"""
|
||||||
generates a random passwort.
|
Generates a random passwort.
|
||||||
"""
|
"""
|
||||||
chars = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
chars = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
||||||
size = 8
|
size = 8
|
||||||
@ -33,21 +33,28 @@ def gen_password():
|
|||||||
|
|
||||||
def gen_username(first_name, last_name):
|
def gen_username(first_name, last_name):
|
||||||
"""
|
"""
|
||||||
generates the username for new users.
|
Generates a username from a first- and lastname.
|
||||||
"""
|
"""
|
||||||
testname = "%s%s" % (first_name.strip(), last_name.strip())
|
first_name = first_name.strip()
|
||||||
try:
|
last_name = last_name.strip()
|
||||||
User.objects.get(username=testname)
|
|
||||||
except User.DoesNotExist:
|
if first_name and last_name:
|
||||||
return testname
|
base_name = " ".join((first_name, last_name))
|
||||||
i = 0
|
else:
|
||||||
|
base_name = first_name or last_name
|
||||||
|
if not base_name:
|
||||||
|
raise ValueError('Either \'first_name\' or \'last_name\' can not be '
|
||||||
|
'empty')
|
||||||
|
|
||||||
|
if not User.objects.filter(username=base_name).exists():
|
||||||
|
return base_name
|
||||||
|
|
||||||
|
counter = 0
|
||||||
while True:
|
while True:
|
||||||
i += 1
|
counter += 1
|
||||||
testname = "%s%s%s" % (first_name, last_name, i)
|
test_name = "%s %d" % (base_name, counter)
|
||||||
try:
|
if not User.objects.filter(username=test_name).exists():
|
||||||
User.objects.get(username=testname)
|
return test_name
|
||||||
except User.DoesNotExist:
|
|
||||||
return testname
|
|
||||||
|
|
||||||
|
|
||||||
def import_users(csv_file):
|
def import_users(csv_file):
|
||||||
|
@ -52,14 +52,23 @@ class UserUpdateForm(UserCreateForm):
|
|||||||
user edits himself and removes the last group containing the permission
|
user edits himself and removes the last group containing the permission
|
||||||
to manage participants.
|
to manage participants.
|
||||||
"""
|
"""
|
||||||
|
user_name = forms.CharField()
|
||||||
|
"""
|
||||||
|
Field to save the username.
|
||||||
|
|
||||||
|
The field username (without the underscore) from the UserModel does not
|
||||||
|
allow whitespaces and umlauts.
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ('username', 'title', 'first_name', 'last_name', 'gender', 'email',
|
fields = ('user_name', 'title', 'first_name', 'last_name', 'gender', 'email',
|
||||||
'groups', 'structure_level', 'committee', 'about_me', 'comment',
|
'groups', 'structure_level', 'committee', 'about_me', 'comment',
|
||||||
'is_active', 'default_password')
|
'is_active', 'default_password')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.request = kwargs.pop('request')
|
self.request = kwargs.pop('request')
|
||||||
|
kwargs['initial']['user_name'] = kwargs['instance'].username
|
||||||
return super(UserUpdateForm, self).__init__(*args, **kwargs)
|
return super(UserUpdateForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def clean(self, *args, **kwargs):
|
def clean(self, *args, **kwargs):
|
||||||
@ -145,15 +154,27 @@ class GroupForm(forms.ModelForm, CssClassMixin):
|
|||||||
return super(GroupForm, self).clean(*args, **kwargs)
|
return super(GroupForm, self).clean(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class UsersettingsForm(forms.ModelForm, CssClassMixin):
|
class UsersettingsForm(CssClassMixin, forms.ModelForm):
|
||||||
|
user_name = forms.CharField()
|
||||||
|
"""
|
||||||
|
Field to save the username.
|
||||||
|
|
||||||
|
The field username (without the underscore) from the UserModel does not
|
||||||
|
allow whitespaces and umlauts.
|
||||||
|
"""
|
||||||
|
|
||||||
language = forms.ChoiceField(choices=settings.LANGUAGES)
|
language = forms.ChoiceField(choices=settings.LANGUAGES)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs['initial']['user_name'] = kwargs['instance'].username
|
||||||
|
return super(UsersettingsForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ('username', 'title', 'first_name', 'last_name', 'gender', 'email',
|
fields = ('user_name', 'title', 'first_name', 'last_name', 'gender', 'email',
|
||||||
'committee', 'about_me')
|
'committee', 'about_me')
|
||||||
|
|
||||||
|
|
||||||
class UserImportForm(forms.Form, CssClassMixin):
|
class UserImportForm(CssClassMixin, forms.Form):
|
||||||
csvfile = forms.FileField(widget=forms.FileInput(attrs={'size': '50'}),
|
csvfile = forms.FileField(widget=forms.FileInput(attrs={'size': '50'}),
|
||||||
label=ugettext_lazy('CSV File'))
|
label=ugettext_lazy('CSV File'))
|
||||||
|
@ -132,6 +132,9 @@ class UserUpdateView(UpdateView):
|
|||||||
form_kwargs.update({'request': self.request})
|
form_kwargs.update({'request': self.request})
|
||||||
return form_kwargs
|
return form_kwargs
|
||||||
|
|
||||||
|
def manipulate_object(self, form):
|
||||||
|
self.object.username = form.cleaned_data['user_name']
|
||||||
|
|
||||||
def post_save(self, form):
|
def post_save(self, form):
|
||||||
super(UserUpdateView, self).post_save(form)
|
super(UserUpdateView, self).post_save(form)
|
||||||
# TODO: find a better solution that makes the following lines obsolete
|
# TODO: find a better solution that makes the following lines obsolete
|
||||||
@ -485,7 +488,9 @@ def user_settings(request):
|
|||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form_user = UsersettingsForm(request.POST, instance=request.user)
|
form_user = UsersettingsForm(request.POST, instance=request.user)
|
||||||
if form_user.is_valid():
|
if form_user.is_valid():
|
||||||
form_user.save()
|
user = form_user.save(commit=False)
|
||||||
|
user.username = form_user.cleaned_data['user_name']
|
||||||
|
user.save()
|
||||||
language = request.LANGUAGE_CODE = \
|
language = request.LANGUAGE_CODE = \
|
||||||
request.session['django_language'] = form_user.cleaned_data['language']
|
request.session['django_language'] = form_user.cleaned_data['language']
|
||||||
activate(language)
|
activate(language)
|
||||||
|
50
tests/participant/test_umlaut_user.py
Normal file
50
tests/participant/test_umlaut_user.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Test Umlaut User
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
:copyright: 2011–2013 by OpenSlides team, see AUTHORS.
|
||||||
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.test.client import Client
|
||||||
|
|
||||||
|
from openslides.utils.test import TestCase
|
||||||
|
from openslides.config.api import config
|
||||||
|
from openslides.participant.models import User, Group
|
||||||
|
|
||||||
|
|
||||||
|
class TestUmlautUser(TestCase):
|
||||||
|
"""
|
||||||
|
Tests persons with umlauts in there name.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user = User.objects.create(username='äöü')
|
||||||
|
self.user.reset_password('äöü')
|
||||||
|
self.client = Client()
|
||||||
|
self.client.login(username='äöü', password='äöü')
|
||||||
|
|
||||||
|
def test_login(self):
|
||||||
|
client = Client()
|
||||||
|
response = client.post('/login/', {'username': 'äöü',
|
||||||
|
'password': 'äöüß'})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
response = client.post('/login/', {'username': 'äöü',
|
||||||
|
'password': 'äöü'})
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
def test_logout(self):
|
||||||
|
response = self.client.get('/logout/')
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
def test_permission(self):
|
||||||
|
response = self.client.get('/participant/1/edit/')
|
||||||
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
|
self.user.groups.add(Group.objects.get(pk=4))
|
||||||
|
|
||||||
|
response = self.client.get('/participant/1/edit/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
37
tests/participant/test_utils.py
Normal file
37
tests/participant/test_utils.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Tests for models of openslides.participant
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
:copyright: 2011–2013 by OpenSlides team, see AUTHORS.
|
||||||
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from openslides.utils.test import TestCase
|
||||||
|
|
||||||
|
from openslides.participant.models import User
|
||||||
|
from openslides.participant.api import gen_username
|
||||||
|
|
||||||
|
|
||||||
|
class UserGenUsername(TestCase):
|
||||||
|
"""
|
||||||
|
Tests for the function gen_username.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_base(self):
|
||||||
|
self.assertEqual(gen_username('foo', 'bar'), 'foo bar')
|
||||||
|
self.assertEqual(gen_username('foo ', ' bar\n'), 'foo bar')
|
||||||
|
self.assertEqual(gen_username('foobar', ''), 'foobar')
|
||||||
|
self.assertEqual(gen_username('', 'foobar'), 'foobar')
|
||||||
|
self.assertRaises(ValueError, gen_username, '', '')
|
||||||
|
|
||||||
|
def test_used_username(self):
|
||||||
|
User.objects.create(username='user name')
|
||||||
|
self.assertEqual(gen_username('user', 'name'), 'user name 1')
|
||||||
|
|
||||||
|
User.objects.create(username='user name 1')
|
||||||
|
self.assertEqual(gen_username('user', 'name'), 'user name 2')
|
||||||
|
|
||||||
|
def test_umlauts(self):
|
||||||
|
self.assertEqual(gen_username('äöü', 'ßüäö'), 'äöü ßüäö')
|
Loading…
Reference in New Issue
Block a user