Compare commits

...

4 Commits

Author SHA1 Message Date
Joaquim Rocha
61149a221e user-accounts: Allow to change the password mode for oneself
This patch modifies the password change dialog in order to allow users
to change their own password mode (i.e. remove or reinstate a password).

Unlike when changing the password for other users, when changing it for
oneself, if a password is currently set, the password change dialog will
require the user to authenticate before modifying the mode or password.
2020-08-26 16:45:35 -07:00
Joaquim Rocha
d34d14a722 user-accounts: Show the correct password mode when changing it
When changing the password for a user, instead of always showing the
first option available ("allow a user to set the password at login") we
should show the mode that is currently set. Besides the obvious
consistency, this avoids e.g. mistakenly change the password mode to
that first option.
2020-08-26 16:45:35 -07:00
Joaquim Rocha
65c7b9569f user-accounts: Allow to remove the password for a user
Since we now support users without passwords, admin users should be
able to set that option for existing users when changing their password.
2020-08-26 16:45:35 -07:00
Joaquim Rocha
b140bdc920 user-accounts: Allow to create a user without a password
This is done by a new radio button reflecting that option.
2020-08-26 16:40:13 -07:00
4 changed files with 129 additions and 26 deletions

View File

@@ -72,6 +72,8 @@ struct _CcAddUserDialog {
GtkLabel *local_hint_label;
GtkEntry *local_name_entry;
GtkComboBoxText *local_username_combo;
GtkRadioButton *local_password_login_radio;
GtkRadioButton *local_no_password_radio;
GtkListStore *local_username_model;
GtkEntry *local_password_entry;
GtkRadioButton *local_password_radio;
@@ -775,13 +777,35 @@ local_password_radio_changed_cb (CcAddUserDialog *self)
gboolean active;
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->local_password_radio));
self->local_password_mode = active ? ACT_USER_PASSWORD_MODE_REGULAR : ACT_USER_PASSWORD_MODE_SET_AT_LOGIN;
gtk_widget_set_sensitive (GTK_WIDGET (self->local_password_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (self->local_verify_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (self->local_strength_indicator), active);
gtk_widget_set_sensitive (GTK_WIDGET (self->local_hint_label), active);
if (!active)
return;
self->local_password_mode = ACT_USER_PASSWORD_MODE_REGULAR;
dialog_validate (self);
}
static void
on_no_password_radio_changed_cb (GtkRadioButton *radio,
gpointer user_data)
{
CcAddUserDialog *self = CC_ADD_USER_DIALOG (user_data);
gboolean active;
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio));
if (!active)
return;
if (radio == GTK_RADIO_BUTTON (self->local_no_password_radio))
self->local_password_mode = ACT_USER_PASSWORD_MODE_NONE;
else
self->local_password_mode = ACT_USER_PASSWORD_MODE_SET_AT_LOGIN;
dialog_validate (self);
}
@@ -1722,6 +1746,8 @@ cc_add_user_dialog_class_init (CcAddUserDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_combo);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_model);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_entry);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_login_radio);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_no_password_radio);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_radio);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_entry);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_hint_label);
@@ -1745,6 +1771,7 @@ cc_add_user_dialog_class_init (CcAddUserDialogClass *klass)
gtk_widget_class_bind_template_callback (widget_class, local_password_entry_icon_press_cb);
gtk_widget_class_bind_template_callback (widget_class, local_password_entry_key_press_event_cb);
gtk_widget_class_bind_template_callback (widget_class, local_password_radio_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_no_password_radio_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, local_username_combo_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, local_username_combo_focus_out_event_cb);
gtk_widget_class_bind_template_callback (widget_class, local_verify_entry_changed_cb);

View File

@@ -273,11 +273,29 @@
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="use_underline">True</property>
<signal name="toggled" handler="on_no_password_radio_changed_cb" object="CcAddUserDialog" swapped="no"/>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="local_no_password_radio">
<property name="label" translatable="yes">Do not re_quire a password when logging in</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">local_password_login_radio</property>
<property name="use_underline">True</property>
<property name="margin_start">12</property>
<signal name="toggled" handler="on_no_password_radio_changed_cb" object="CcAddUserDialog" swapped="no"/>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="local_password_radio">
<property name="label" translatable="yes">Set a password _now</property>
@@ -291,7 +309,7 @@
<signal name="toggled" handler="local_password_radio_changed_cb" object="CcAddUserDialog" swapped="yes"/>
</object>
<packing>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
</object>

View File

@@ -45,6 +45,7 @@ struct _CcPasswordDialog
GtkBox *action_radio_box;
GtkRadioButton *action_now_radio;
GtkRadioButton *action_login_radio;
GtkRadioButton *action_no_password_radio;
GtkButton *ok_button;
GtkLabel *old_password_label;
GtkEntry *old_password_entry;
@@ -188,6 +189,15 @@ ok_button_clicked_cb (CcPasswordDialog *self)
act_user_set_automatic_login (self->user, FALSE);
break;
case ACT_USER_PASSWORD_MODE_NONE:
/* When setting the user password mode to none, when it
* was previously set-at-login, we need to reset the password,
* otherwise the mode will be set back to set-at-login */
if (act_user_get_password_mode (self->user) == ACT_USER_PASSWORD_MODE_SET_AT_LOGIN)
act_user_set_password (self->user, "", "");
act_user_set_password_mode (self->user, self->password_mode);
break;
default:
g_assert_not_reached ();
}
@@ -199,7 +209,7 @@ static void
update_sensitivity (CcPasswordDialog *self)
{
const gchar *password, *verify;
gboolean can_change;
gboolean can_change = TRUE;
int strength;
password = gtk_entry_get_text (self->password_entry);
@@ -210,8 +220,8 @@ update_sensitivity (CcPasswordDialog *self)
can_change = strength > 1 && strcmp (password, verify) == 0 &&
(self->old_password_ok || !gtk_widget_get_visible (GTK_WIDGET (self->old_password_entry)));
}
else {
can_change = TRUE;
else if (self->password_mode == ACT_USER_PASSWORD_MODE_NONE) {
can_change = self->old_password_ok || !gtk_widget_get_visible (GTK_WIDGET (self->old_password_entry));
}
gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button), can_change);
@@ -222,30 +232,59 @@ mode_change (CcPasswordDialog *self,
ActUserPasswordMode mode)
{
gboolean active;
gboolean user_is_self = (act_user_get_uid (self->user) == getuid ());
active = (mode == ACT_USER_PASSWORD_MODE_REGULAR);
gtk_widget_set_sensitive (GTK_WIDGET (self->password_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (self->verify_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (self->old_password_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (self->password_hint_label), active);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->action_now_radio), active);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->action_login_radio), !active);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->action_login_radio),
(mode == ACT_USER_PASSWORD_MODE_SET_AT_LOGIN));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->action_no_password_radio),
(mode == ACT_USER_PASSWORD_MODE_NONE));
if (user_is_self) {
gtk_widget_set_sensitive (GTK_WIDGET (self->old_password_entry),
act_user_get_password_mode (self->user) == ACT_USER_PASSWORD_MODE_REGULAR);
}
self->password_mode = mode;
update_sensitivity (self);
}
static void
action_now_radio_toggled_cb (CcPasswordDialog *self)
set_password_mode_from_radio_button (GtkRadioButton *radio,
CcPasswordDialog *self,
ActUserPasswordMode mode)
{
gint active;
ActUserPasswordMode mode;
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio)))
return;
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->action_now_radio));
mode = active ? ACT_USER_PASSWORD_MODE_REGULAR : ACT_USER_PASSWORD_MODE_SET_AT_LOGIN;
mode_change (self, mode);
}
static void
password_now_radio_toggled_cb (GtkRadioButton *radio,
CcPasswordDialog *self)
{
set_password_mode_from_radio_button (radio, self, ACT_USER_PASSWORD_MODE_REGULAR);
}
static void
no_password_radio_toggled_cb (GtkRadioButton *radio,
CcPasswordDialog *self)
{
set_password_mode_from_radio_button (radio, self, ACT_USER_PASSWORD_MODE_NONE);
}
static void
password_login_radio_toggled_cb (GtkRadioButton *radio,
CcPasswordDialog *self)
{
set_password_mode_from_radio_button (radio, self, ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
}
static void
update_password_match (CcPasswordDialog *self)
{
@@ -463,6 +502,7 @@ cc_password_dialog_class_init (CcPasswordDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_radio_box);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_now_radio);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_no_password_radio);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_login_radio);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, ok_button);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, old_password_label);
@@ -473,7 +513,7 @@ cc_password_dialog_class_init (CcPasswordDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, verify_entry);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, verify_hint_label);
gtk_widget_class_bind_template_callback (widget_class, action_now_radio_toggled_cb);
gtk_widget_class_bind_template_callback (widget_class, no_password_radio_toggled_cb);
gtk_widget_class_bind_template_callback (widget_class, old_password_entry_changed);
gtk_widget_class_bind_template_callback (widget_class, old_password_entry_focus_out_cb);
gtk_widget_class_bind_template_callback (widget_class, ok_button_clicked_cb);
@@ -481,6 +521,8 @@ cc_password_dialog_class_init (CcPasswordDialogClass *klass)
gtk_widget_class_bind_template_callback (widget_class, password_entry_focus_out_cb);
gtk_widget_class_bind_template_callback (widget_class, password_entry_icon_press_cb);
gtk_widget_class_bind_template_callback (widget_class, password_entry_key_press_cb);
gtk_widget_class_bind_template_callback (widget_class, password_login_radio_toggled_cb);
gtk_widget_class_bind_template_callback (widget_class, password_now_radio_toggled_cb);
gtk_widget_class_bind_template_callback (widget_class, verify_entry_changed);
}
@@ -504,14 +546,15 @@ cc_password_dialog_new (ActUser *user)
NULL);
self->user = g_object_ref (user);
gtk_widget_show_all (GTK_WIDGET (self->action_radio_box));
if (act_user_get_uid (self->user) == getuid ()) {
gboolean visible;
mode_change (self, ACT_USER_PASSWORD_MODE_REGULAR);
gtk_widget_hide (GTK_WIDGET (self->action_radio_box));
visible = (act_user_get_password_mode (user) != ACT_USER_PASSWORD_MODE_NONE);
gtk_widget_hide (GTK_WIDGET (self->action_login_radio));
gtk_widget_set_visible (GTK_WIDGET (self->old_password_label), visible);
gtk_widget_set_visible (GTK_WIDGET (self->old_password_entry), visible);
self->old_password_ok = !visible;
@@ -519,8 +562,7 @@ cc_password_dialog_new (ActUser *user)
self->passwd_handler = passwd_init ();
}
else {
mode_change (self, ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
gtk_widget_show (GTK_WIDGET (self->action_radio_box));
mode_change (self, act_user_get_password_mode (user));
gtk_widget_hide (GTK_WIDGET (self->old_password_label));
gtk_widget_hide (GTK_WIDGET (self->old_password_entry));

View File

@@ -218,13 +218,10 @@
<property name="mnemonic_widget">old_password_entry</property>
<property name="margin_start">25</property>
<property name="margin_bottom">12</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
@@ -242,7 +239,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
@@ -251,36 +248,55 @@
<property name="orientation">vertical</property>
<child>
<object class="GtkRadioButton" id="action_login_radio">
<property name="label" translatable="yes">Allow user to change their password on next login</property>
<property name="label" translatable="yes">Allow user to set a password when they next _login</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="use_underline">True</property>
<signal name="toggled" handler="password_login_radio_toggled_cb" object="CcPasswordDialog" swapped="no"/>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="action_now_radio">
<property name="label" translatable="yes">Set a password now</property>
<object class="GtkRadioButton" id="action_no_password_radio">
<property name="label" translatable="yes">Do not re_quire a password when logging in</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">action_login_radio</property>
<signal name="toggled" handler="action_now_radio_toggled_cb" object="CcPasswordDialog" swapped="yes"/>
<property name="use_underline">True</property>
<signal name="toggled" handler="no_password_radio_toggled_cb" object="CcPasswordDialog" swapped="no"/>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="action_now_radio">
<property name="label" translatable="yes">Set a password _now</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">action_login_radio</property>
<property name="use_underline">True</property>
<signal name="toggled" handler="password_now_radio_toggled_cb" object="CcPasswordDialog" swapped="no"/>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="top_attach">3</property>
<property name="width">3</property>
</packing>
</child>