users: Add email address field when creating/updating user accounts

Closes: #1826.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
This commit is contained in:
Sunil Mohan Adapa 2024-03-13 00:29:05 -07:00 committed by Veiko Aasa
parent a3b6506a4e
commit 9d2a11b874
No known key found for this signature in database
GPG Key ID: 478539CAE680674E
3 changed files with 50 additions and 10 deletions

View File

@ -59,6 +59,18 @@ def _create_django_groups():
return group_choices
class EmailFieldMixin:
"""Mixin to set common properties for the email field."""
def __init__(self, *args, **kwargs):
"""Set basic properties for the email field."""
super().__init__(*args, **kwargs)
self.fields['email'].help_text = _(
'Optional. Used to send emails to reset password and important '
'notifications.')
class GroupsFieldMixin:
"""Mixin to set common properties for the group field."""
@ -146,8 +158,8 @@ class PasswordConfirmForm(forms.Form):
return confirm_password
class CreateUserForm(ValidNewUsernameCheckMixin, GroupsFieldMixin,
plinth.forms.LanguageSelectionFormMixin,
class CreateUserForm(ValidNewUsernameCheckMixin, EmailFieldMixin,
GroupsFieldMixin, plinth.forms.LanguageSelectionFormMixin,
PasswordConfirmForm, UserCreationForm):
"""Custom user create form.
@ -161,8 +173,8 @@ class CreateUserForm(ValidNewUsernameCheckMixin, GroupsFieldMixin,
class Meta(UserCreationForm.Meta):
"""Metadata to control automatic form building."""
fields = ('username', 'password1', 'password2', 'groups', 'language',
'confirm_password')
fields = ('username', 'email', 'password1', 'password2', 'groups',
'language', 'confirm_password')
widgets = {
'groups': plinth.forms.CheckboxSelectMultiple(),
}
@ -219,8 +231,8 @@ class CreateUserForm(ValidNewUsernameCheckMixin, GroupsFieldMixin,
class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm,
GroupsFieldMixin, plinth.forms.LanguageSelectionFormMixin,
forms.ModelForm):
EmailFieldMixin, GroupsFieldMixin,
plinth.forms.LanguageSelectionFormMixin, forms.ModelForm):
"""When user info is changed, also updates LDAP user."""
username = USERNAME_FIELD
@ -238,8 +250,8 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm,
class Meta:
"""Metadata to control automatic form building."""
fields = ('username', 'groups', 'ssh_keys', 'language', 'is_active',
'confirm_password')
fields = ('username', 'email', 'groups', 'ssh_keys', 'language',
'is_active', 'confirm_password')
model = User
widgets = {
'groups': plinth.forms.CheckboxSelectMultipleWithReadOnly(),

View File

@ -65,8 +65,9 @@ def test_create_user(session_browser):
if functional.user_exists(session_browser, 'alice'):
functional.delete_user(session_browser, 'alice')
functional.create_user(session_browser, 'alice')
functional.create_user(session_browser, 'alice', email='alice@example.com')
assert functional.user_exists(session_browser, 'alice')
assert _get_email(session_browser, 'alice') == 'alice@example.com'
def test_rename_user(session_browser):
@ -133,6 +134,17 @@ def test_users_cannot_connect_passwordless_over_ssh(session_browser,
tmp_path_factory)
def test_update_user(session_browser):
"""Test changing properties of a user."""
functional.create_user(session_browser, 'alice', email='alice@example.com')
# Update email
_set_email(session_browser, 'alice', 'alice1@example.com')
assert _get_email(session_browser, 'alice') == 'alice1@example.com'
_set_email(session_browser, 'alice', 'alice2@example.com')
assert _get_email(session_browser, 'alice') == 'alice2@example.com'
@pytest.mark.parametrize('language_code', _language_codes.values())
def test_change_language(session_browser, language_code):
"""Test changing the language."""
@ -254,6 +266,20 @@ def _rename_user(browser, old_name, new_name):
functional.submit(browser, form_class='form-update')
def _set_email(browser, username, email):
"""Set the email field value for a user."""
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username))
browser.find_by_id('id_email').fill(email)
browser.find_by_id('id_confirm_password').fill(_admin_password)
functional.submit(browser, form_class='form-update')
def _get_email(browser, username):
"""Return the email field value for a user."""
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username))
return browser.find_by_id('id_email').value
def _set_language(browser, language_code):
username = functional.config['DEFAULT']['username']
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username))

View File

@ -599,7 +599,7 @@ def get_forwarders(browser):
##############################
def create_user(browser, name, password=None, groups=[]):
def create_user(browser, name, password=None, groups=[], email=None):
"""Create a user with password and user groups."""
nav_to_module(browser, 'users')
@ -612,6 +612,8 @@ def create_user(browser, name, password=None, groups=[]):
browser.find_by_id('id_username').fill(name)
browser.find_by_id('id_password1').fill(password)
browser.find_by_id('id_password2').fill(password)
if email:
browser.find_by_id('id_email').fill(email)
for group in groups:
browser.find_by_xpath(