manager: dont require username or email for passwordless accounts (fixes #28916)

This commit is contained in:
Benjamin Dauvergne 2018-12-13 16:18:28 +01:00
parent 5a4dbd9df7
commit 506de394f9
2 changed files with 31 additions and 13 deletions

View File

@ -193,7 +193,9 @@ class UserEditForm(LimitQuerysetFormMixin, CssClass, BaseUserForm):
self.data._mutable = False self.data._mutable = False
def clean(self): def clean(self):
if 'username' in self.fields or 'email' in self.fields: if (self.instance.has_usable_password() and (
'username' in self.fields or
'email' in self.fields)):
if not self.cleaned_data.get('username') and \ if not self.cleaned_data.get('username') and \
not self.cleaned_data.get('email'): not self.cleaned_data.get('email'):
raise forms.ValidationError( raise forms.ValidationError(
@ -234,6 +236,7 @@ class UserChangePasswordForm(CssClass, forms.ModelForm):
} }
notification_template_prefix = \ notification_template_prefix = \
'authentic2/manager/change-password-notification' 'authentic2/manager/change-password-notification'
require_password = True
def clean_password2(self): def clean_password2(self):
password1 = self.cleaned_data.get("password1") password1 = self.cleaned_data.get("password1")
@ -247,20 +250,24 @@ class UserChangePasswordForm(CssClass, forms.ModelForm):
def clean(self): def clean(self):
super(UserChangePasswordForm, self).clean() super(UserChangePasswordForm, self).clean()
if not self.cleaned_data.get('generate_password') \ if (self.require_password and
and not self.cleaned_data.get('password1') \ not self.cleaned_data.get('generate_password') and
and not self.cleaned_data.get('send_password_reset'): not self.cleaned_data.get('password1') and
not self.cleaned_data.get('send_password_reset')):
raise forms.ValidationError( raise forms.ValidationError(
_('You must choose password generation or type a new' _('You must choose password generation or type a new'
' one or send a password reset mail')) ' one or send a password reset mail'))
if (self.instance and self.instance.pk and not self.instance.email and if (not self.has_email() and
(self.cleaned_data.get('send_mail') (self.cleaned_data.get('send_mail') or
or self.cleaned_data.get('generate_password' self.cleaned_data.get('generate_password' or
or self.cleaned_data.get('send_password_reset')))): self.cleaned_data.get('send_password_reset')))):
raise forms.ValidationError( raise forms.ValidationError(
_('User does not have a mail, we cannot send the ' _('User does not have a mail, we cannot send the '
'informations to him.')) 'informations to him.'))
def has_email(self):
return bool(self.instance and self.instance.email)
def save(self, commit=True): def save(self, commit=True):
user = super(UserChangePasswordForm, self).save(commit=False) user = super(UserChangePasswordForm, self).save(commit=False)
new_password = None new_password = None
@ -297,7 +304,7 @@ class UserChangePasswordForm(CssClass, forms.ModelForm):
label=_("Confirmation"), label=_("Confirmation"),
required=False) required=False)
send_mail = forms.BooleanField( send_mail = forms.BooleanField(
initial=True, initial=False,
label=_('Send informations to user'), label=_('Send informations to user'),
required=False) required=False)
@ -309,6 +316,7 @@ class UserChangePasswordForm(CssClass, forms.ModelForm):
class UserAddForm(UserChangePasswordForm, UserEditForm): class UserAddForm(UserChangePasswordForm, UserEditForm):
css_class = "user-form" css_class = "user-form"
form_id = "id_user_add_form" form_id = "id_user_add_form"
require_password = False
notification_template_prefix = \ notification_template_prefix = \
'authentic2/manager/new-account-notification' 'authentic2/manager/new-account-notification'
@ -328,12 +336,21 @@ class UserAddForm(UserChangePasswordForm, UserEditForm):
def clean(self): def clean(self):
super(UserAddForm, self).clean() super(UserAddForm, self).clean()
User = get_user_model() # check if this account is going to be real online account, i.e. with a
# password, it it's the case complain that there is no identifiers.
has_password = (
self.cleaned_data.get('new_password1') or
self.cleaned_data.get('generate_password') or
self.cleaned_data.get('send_password_reset'))
if not self.cleaned_data.get('username') and \ if (has_password and
not self.cleaned_data.get('email'): not self.cleaned_data.get('username') and
not self.cleaned_data.get('email')):
raise forms.ValidationError( raise forms.ValidationError(
_('You must set a username or an email.')) _('You must set a username or an email to set a password or send an activation link.'))
def has_email(self):
return bool(self.cleaned_data.get('email'))
def save(self, commit=True): def save(self, commit=True):
self.instance.ou = self.ou self.instance.ou = self.ou

View File

@ -150,6 +150,7 @@ def test_manager_stress_create_user(superuser_or_admin, app, mailoutbox):
form.set('email', 'john.doe@gmail.com') form.set('email', 'john.doe@gmail.com')
form.set('password1', 'ABcd1234') form.set('password1', 'ABcd1234')
form.set('password2', 'ABcd1234') form.set('password2', 'ABcd1234')
form.set('send_mail', True)
form.submit().follow() form.submit().follow()
app.get('/logout/').form.submit() app.get('/logout/').form.submit()
assert User.objects.filter(ou_id=new_ou.id).count() == 100 assert User.objects.filter(ou_id=new_ou.id).count() == 100