From 8397fe574ff149c87f94ca6be7c559d3892db0a8 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 13 Dec 2018 16:18:28 +0100 Subject: [PATCH 1/2] manager: dont require username or email for passwordless accounts (fixes #28916) --- src/authentic2/manager/forms.py | 45 +++++++++++++++++++++++---------- tests/test_manager.py | 1 + 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/authentic2/manager/forms.py b/src/authentic2/manager/forms.py index 8ef7f073..f42a0511 100644 --- a/src/authentic2/manager/forms.py +++ b/src/authentic2/manager/forms.py @@ -193,7 +193,9 @@ class UserEditForm(LimitQuerysetFormMixin, CssClass, BaseUserForm): self.data._mutable = False 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 \ not self.cleaned_data.get('email'): raise forms.ValidationError( @@ -234,6 +236,7 @@ class UserChangePasswordForm(CssClass, forms.ModelForm): } notification_template_prefix = \ 'authentic2/manager/change-password-notification' + require_password = True def clean_password2(self): password1 = self.cleaned_data.get("password1") @@ -247,20 +250,24 @@ class UserChangePasswordForm(CssClass, forms.ModelForm): def clean(self): super(UserChangePasswordForm, self).clean() - if not self.cleaned_data.get('generate_password') \ - and not self.cleaned_data.get('password1') \ - and not self.cleaned_data.get('send_password_reset'): + if (self.require_password and + not self.cleaned_data.get('generate_password') and + not self.cleaned_data.get('password1') and + not self.cleaned_data.get('send_password_reset')): raise forms.ValidationError( _('You must choose password generation or type a new' ' one or send a password reset mail')) - if (self.instance and self.instance.pk and not self.instance.email and - (self.cleaned_data.get('send_mail') - or self.cleaned_data.get('generate_password' - or self.cleaned_data.get('send_password_reset')))): + if (not self.has_email() and + (self.cleaned_data.get('send_mail') or + self.cleaned_data.get('generate_password' or + self.cleaned_data.get('send_password_reset')))): raise forms.ValidationError( _('User does not have a mail, we cannot send the ' 'informations to him.')) + def has_email(self): + return bool(self.instance and self.instance.email) + def save(self, commit=True): user = super(UserChangePasswordForm, self).save(commit=False) new_password = None @@ -297,7 +304,7 @@ class UserChangePasswordForm(CssClass, forms.ModelForm): label=_("Confirmation"), required=False) send_mail = forms.BooleanField( - initial=True, + initial=False, label=_('Send informations to user'), required=False) @@ -309,6 +316,7 @@ class UserChangePasswordForm(CssClass, forms.ModelForm): class UserAddForm(UserChangePasswordForm, UserEditForm): css_class = "user-form" form_id = "id_user_add_form" + require_password = False notification_template_prefix = \ 'authentic2/manager/new-account-notification' @@ -328,12 +336,21 @@ class UserAddForm(UserChangePasswordForm, UserEditForm): def clean(self): super(UserAddForm, self).clean() - User = get_user_model() - - if not self.cleaned_data.get('username') and \ - not self.cleaned_data.get('email'): + # 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 (has_password and + not self.cleaned_data.get('username') and + not self.cleaned_data.get('email')): 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): self.instance.ou = self.ou diff --git a/tests/test_manager.py b/tests/test_manager.py index 33bec66b..916f2c76 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -150,6 +150,7 @@ def test_manager_stress_create_user(superuser_or_admin, app, mailoutbox): form.set('email', 'john.doe@gmail.com') form.set('password1', 'ABcd1234') form.set('password2', 'ABcd1234') + form.set('send_mail', True) form.submit().follow() app.get('/logout/').form.submit() assert User.objects.filter(ou_id=new_ou.id).count() == 100 -- 2.18.0