user-accounts: Rename UmPasswordDialog to CcPasswordDialog

Um is a naming hangover from before this was part of g-c-c.
This commit is contained in:
Robert Ancell 2018-11-07 09:28:46 +13:00
parent 2f68113950
commit 8029b3e7be
8 changed files with 557 additions and 557 deletions

View file

@ -0,0 +1,532 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright 2009-2010 Red Hat, Inc,
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Written by: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <act/act.h>
#include "cc-password-dialog.h"
#include "pw-utils.h"
#include "run-passwd.h"
#include "um-resources.h"
#include "um-utils.h"
#define PASSWORD_CHECK_TIMEOUT 600
struct _CcPasswordDialog
{
GtkDialog parent_instance;
GtkBox *action_radio_box;
GtkRadioButton *action_now_radio;
GtkRadioButton *action_login_radio;
GtkButton *ok_button;
GtkLabel *old_password_label;
GtkEntry *old_password_entry;
GtkEntry *password_entry;
GtkLabel *password_hint_label;
GtkLevelBar *strength_indicator;
GtkEntry *verify_entry;
GtkLabel *verify_hint_label;
gint password_entry_timeout_id;
ActUser *user;
ActUserPasswordMode password_mode;
gboolean old_password_ok;
gint old_password_entry_timeout_id;
PasswdHandler *passwd_handler;
};
G_DEFINE_TYPE (CcPasswordDialog, cc_password_dialog, GTK_TYPE_DIALOG)
static gint
update_password_strength (CcPasswordDialog *self)
{
const gchar *password;
const gchar *old_password;
const gchar *username;
gint strength_level;
const gchar *hint;
const gchar *verify;
password = gtk_entry_get_text (self->password_entry);
old_password = gtk_entry_get_text (self->old_password_entry);
username = act_user_get_user_name (self->user);
pw_strength (password, old_password, username,
&hint, &strength_level);
gtk_level_bar_set_value (self->strength_indicator, strength_level);
gtk_label_set_label (self->password_hint_label, hint);
if (strength_level > 1) {
set_entry_validation_checkmark (self->password_entry);
} else if (strlen (password) == 0) {
set_entry_generation_icon (self->password_entry);
} else {
clear_entry_validation_error (self->password_entry);
}
verify = gtk_entry_get_text (self->verify_entry);
if (strlen (verify) == 0) {
gtk_widget_set_sensitive (GTK_WIDGET (self->verify_entry), strength_level > 1);
}
return strength_level;
}
static void
password_changed_cb (PasswdHandler *handler,
GError *error,
CcPasswordDialog *self)
{
GtkWidget *dialog;
const gchar *primary_text;
const gchar *secondary_text;
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (self)), NULL);
if (!error) {
gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
return;
}
if (error->code == PASSWD_ERROR_REJECTED) {
primary_text = error->message;
secondary_text = _("Please choose another password.");
gtk_entry_set_text (self->password_entry, "");
gtk_widget_grab_focus (GTK_WIDGET (self->password_entry));
gtk_entry_set_text (self->verify_entry, "");
}
else if (error->code == PASSWD_ERROR_AUTH_FAILED) {
primary_text = error->message;
secondary_text = _("Please type your current password again.");
gtk_entry_set_text (self->old_password_entry, "");
gtk_widget_grab_focus (GTK_WIDGET (self->old_password_entry));
}
else {
primary_text = _("Password could not be changed");
secondary_text = error->message;
}
dialog = gtk_message_dialog_new (GTK_WINDOW (self),
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s", primary_text);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", secondary_text);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
static void
ok_button_clicked_cb (CcPasswordDialog *self)
{
const gchar *password;
password = gtk_entry_get_text (self->password_entry);
switch (self->password_mode) {
case ACT_USER_PASSWORD_MODE_REGULAR:
if (act_user_get_uid (self->user) == getuid ()) {
GdkDisplay *display;
g_autoptr(GdkCursor) cursor = NULL;
/* When setting a password for the current user,
* use passwd directly, to preserve the audit trail
* and to e.g. update the keyring password.
*/
passwd_change_password (self->passwd_handler, password,
(PasswdCallback) password_changed_cb, self);
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
display = gtk_widget_get_display (GTK_WIDGET (self));
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (self)), cursor);
gdk_display_flush (display);
return;
}
act_user_set_password_mode (self->user, ACT_USER_PASSWORD_MODE_REGULAR);
act_user_set_password (self->user, password, "");
break;
case ACT_USER_PASSWORD_MODE_SET_AT_LOGIN:
act_user_set_password_mode (self->user, self->password_mode);
act_user_set_automatic_login (self->user, FALSE);
break;
default:
g_assert_not_reached ();
}
gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
}
static void
update_sensitivity (CcPasswordDialog *self)
{
const gchar *password, *verify;
gboolean can_change;
int strength;
password = gtk_entry_get_text (self->password_entry);
verify = gtk_entry_get_text (self->verify_entry);
if (self->password_mode == ACT_USER_PASSWORD_MODE_REGULAR) {
strength = update_password_strength (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;
}
gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button), can_change);
}
static void
mode_change (CcPasswordDialog *self,
ActUserPasswordMode mode)
{
gboolean active;
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);
self->password_mode = mode;
update_sensitivity (self);
}
static void
action_now_radio_toggled_cb (CcPasswordDialog *self)
{
gint active;
ActUserPasswordMode mode;
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
update_password_match (CcPasswordDialog *self)
{
const gchar *password;
const gchar *verify;
const gchar *message = "";
password = gtk_entry_get_text (self->password_entry);
verify = gtk_entry_get_text (self->verify_entry);
if (strlen (verify) > 0) {
if (strcmp (password, verify) != 0) {
message = _("The passwords do not match.");
}
else {
set_entry_validation_checkmark (self->verify_entry);
}
}
gtk_label_set_label (self->verify_hint_label, message);
}
static gboolean
password_entry_timeout (CcPasswordDialog *self)
{
update_password_strength (self);
update_sensitivity (self);
update_password_match (self);
self->password_entry_timeout_id = 0;
return FALSE;
}
static void
recheck_password_match (CcPasswordDialog *self)
{
const gchar *password;
if (self->password_entry_timeout_id != 0) {
g_source_remove (self->password_entry_timeout_id);
self->password_entry_timeout_id = 0;
}
gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button), FALSE);
password = gtk_entry_get_text (self->password_entry);
if (strlen (password) == 0) {
gtk_entry_set_visibility (self->password_entry, FALSE);
}
self->password_entry_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT,
(GSourceFunc) password_entry_timeout,
self);
}
static void
password_entry_changed (CcPasswordDialog *self)
{
clear_entry_validation_error (self->password_entry);
clear_entry_validation_error (self->verify_entry);
recheck_password_match (self);
}
static void
verify_entry_changed (CcPasswordDialog *self)
{
clear_entry_validation_error (self->verify_entry);
recheck_password_match (self);
}
static gboolean
password_entry_focus_out_cb (CcPasswordDialog *self)
{
if (self->password_entry_timeout_id != 0) {
g_source_remove (self->password_entry_timeout_id);
self->password_entry_timeout_id = 0;
}
password_entry_timeout (self);
return FALSE;
}
static gboolean
password_entry_key_press_cb (CcPasswordDialog *self,
GdkEvent *event)
{
GdkEventKey *key = (GdkEventKey *)event;
if (key->keyval == GDK_KEY_Tab)
password_entry_timeout (self);
return FALSE;
}
static void
auth_cb (PasswdHandler *handler,
GError *error,
CcPasswordDialog *self)
{
if (error) {
self->old_password_ok = FALSE;
}
else {
self->old_password_ok = TRUE;
set_entry_validation_checkmark (self->old_password_entry);
}
update_sensitivity (self);
}
static gboolean
old_password_entry_timeout (CcPasswordDialog *self)
{
const gchar *text;
update_sensitivity (self);
text = gtk_entry_get_text (self->old_password_entry);
if (!self->old_password_ok) {
passwd_authenticate (self->passwd_handler, text, (PasswdCallback)auth_cb, self);
}
self->old_password_entry_timeout_id = 0;
return FALSE;
}
static gboolean
old_password_entry_focus_out_cb (CcPasswordDialog *self)
{
if (self->old_password_entry_timeout_id != 0) {
g_source_remove (self->old_password_entry_timeout_id);
self->old_password_entry_timeout_id = 0;
}
old_password_entry_timeout (self);
return FALSE;
}
static void
old_password_entry_changed (CcPasswordDialog *self)
{
if (self->old_password_entry_timeout_id != 0) {
g_source_remove (self->old_password_entry_timeout_id);
self->old_password_entry_timeout_id = 0;
}
clear_entry_validation_error (self->old_password_entry);
gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button), FALSE);
self->old_password_ok = FALSE;
self->old_password_entry_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT,
(GSourceFunc) old_password_entry_timeout,
self);
}
static void
password_entry_icon_press_cb (CcPasswordDialog *self)
{
g_autofree gchar *pwd = NULL;
pwd = pw_generate ();
if (pwd == NULL)
return;
gtk_entry_set_text (self->password_entry, pwd);
gtk_entry_set_text (self->verify_entry, pwd);
gtk_entry_set_visibility (self->password_entry, TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (self->verify_entry), TRUE);
}
static void
cc_password_dialog_dispose (GObject *object)
{
CcPasswordDialog *self = CC_PASSWORD_DIALOG (object);
g_clear_object (&self->user);
if (self->passwd_handler) {
passwd_destroy (self->passwd_handler);
self->passwd_handler = NULL;
}
if (self->old_password_entry_timeout_id != 0) {
g_source_remove (self->old_password_entry_timeout_id);
self->old_password_entry_timeout_id = 0;
}
if (self->password_entry_timeout_id != 0) {
g_source_remove (self->password_entry_timeout_id);
self->password_entry_timeout_id = 0;
}
G_OBJECT_CLASS (cc_password_dialog_parent_class)->dispose (object);
}
static void
cc_password_dialog_class_init (CcPasswordDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = cc_password_dialog_dispose;
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/user-accounts/cc-password-dialog.ui");
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_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);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, old_password_entry);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_entry);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_hint_label);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, strength_indicator);
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, 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);
gtk_widget_class_bind_template_callback (widget_class, password_entry_changed);
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_entry_timeout);
gtk_widget_class_bind_template_callback (widget_class, verify_entry_changed);
}
static void
cc_password_dialog_init (CcPasswordDialog *self)
{
g_resources_register (um_get_resource ());
gtk_widget_init_template (GTK_WIDGET (self));
}
CcPasswordDialog *
cc_password_dialog_new (ActUser *user)
{
CcPasswordDialog *self;
g_return_val_if_fail (ACT_IS_USER (user), NULL);
self = g_object_new (CC_TYPE_PASSWORD_DIALOG,
"use-header-bar", 1,
NULL);
self->user = g_object_ref (user);
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_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;
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));
gtk_widget_hide (GTK_WIDGET (self->old_password_label));
gtk_widget_hide (GTK_WIDGET (self->old_password_entry));
self->old_password_ok = TRUE;
}
if (self->old_password_ok == FALSE)
gtk_widget_grab_focus (GTK_WIDGET (self->old_password_entry));
else
gtk_widget_grab_focus (GTK_WIDGET (self->password_entry));
gtk_widget_grab_default (GTK_WIDGET (self->ok_button));
return self;
}

View file

@ -25,9 +25,9 @@
G_BEGIN_DECLS
#define UM_TYPE_PASSWORD_DIALOG (um_password_dialog_get_type ())
G_DECLARE_FINAL_TYPE (UmPasswordDialog, um_password_dialog, UM, PASSWORD_DIALOG, GtkDialog)
#define CC_TYPE_PASSWORD_DIALOG (cc_password_dialog_get_type ())
G_DECLARE_FINAL_TYPE (CcPasswordDialog, cc_password_dialog, CC, PASSWORD_DIALOG, GtkDialog)
UmPasswordDialog *um_password_dialog_new (ActUser *user);
CcPasswordDialog *cc_password_dialog_new (ActUser *user);
G_END_DECLS

View file

@ -2,7 +2,7 @@
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<template class="UmPasswordDialog" parent="GtkDialog">
<template class="CcPasswordDialog" parent="GtkDialog">
<property name="border_width">6</property>
<property name="title" translatable="yes">Change Password</property>
<property name="resizable">False</property>
@ -41,7 +41,7 @@
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
<signal name="clicked" handler="ok_button_clicked_cb" object="UmPasswordDialog" swapped="yes"/>
<signal name="clicked" handler="ok_button_clicked_cb" object="CcPasswordDialog" swapped="yes"/>
<style>
<class name="text-button"/>
<class name="suggested-action"/>
@ -80,9 +80,9 @@
<property name="hexpand">True</property>
<property name="activates_default">True</property>
<property name="input_purpose">password</property>
<signal name="notify::text" handler="verify_entry_changed" object="UmPasswordDialog" swapped="yes"/>
<signal name="activate" handler="password_entry_timeout" object="UmPasswordDialog" swapped="yes"/>
<signal name="focus-out-event" handler="password_entry_focus_out_cb" after="yes" object="UmPasswordDialog" swapped="yes"/>
<signal name="notify::text" handler="verify_entry_changed" object="CcPasswordDialog" swapped="yes"/>
<signal name="activate" handler="password_entry_timeout" object="CcPasswordDialog" swapped="yes"/>
<signal name="focus-out-event" handler="password_entry_focus_out_cb" after="yes" object="CcPasswordDialog" swapped="yes"/>
</object>
<packing>
<property name="left_attach">1</property>
@ -180,11 +180,11 @@
<property name="hexpand">True</property>
<property name="activates_default">True</property>
<property name="input_purpose">password</property>
<signal name="notify::text" handler="password_entry_changed" object="UmPasswordDialog" swapped="yes"/>
<signal name="activate" handler="password_entry_timeout" object="UmPasswordDialog" swapped="yes"/>
<signal name="focus-out-event" handler="password_entry_focus_out_cb" after="yes" object="UmPasswordDialog" swapped="yes"/>
<signal name="key-press-event" handler="password_entry_key_press_cb" object="UmPasswordDialog" swapped="yes"/>
<signal name="icon-press" handler="password_entry_icon_press_cb" object="UmPasswordDialog" swapped="yes"/>
<signal name="notify::text" handler="password_entry_changed" object="CcPasswordDialog" swapped="yes"/>
<signal name="activate" handler="password_entry_timeout" object="CcPasswordDialog" swapped="yes"/>
<signal name="focus-out-event" handler="password_entry_focus_out_cb" after="yes" object="CcPasswordDialog" swapped="yes"/>
<signal name="key-press-event" handler="password_entry_key_press_cb" object="CcPasswordDialog" swapped="yes"/>
<signal name="icon-press" handler="password_entry_icon_press_cb" object="CcPasswordDialog" swapped="yes"/>
</object>
<packing>
<property name="left_attach">1</property>
@ -236,9 +236,9 @@
<property name="activates_default">True</property>
<property name="margin_bottom">12</property>
<property name="input_purpose">password</property>
<signal name="notify::text" handler="old_password_entry_changed" object="UmPasswordDialog" swapped="yes"/>
<signal name="activate" handler="password_entry_timeout" object="UmPasswordDialog" swapped="yes"/>
<signal name="focus-out-event" handler="old_password_entry_focus_out_cb" after="yes" object="UmPasswordDialog" swapped="yes"/>
<signal name="notify::text" handler="old_password_entry_changed" object="CcPasswordDialog" swapped="yes"/>
<signal name="activate" handler="password_entry_timeout" object="CcPasswordDialog" swapped="yes"/>
<signal name="focus-out-event" handler="old_password_entry_focus_out_cb" after="yes" object="CcPasswordDialog" swapped="yes"/>
</object>
<packing>
<property name="left_attach">1</property>
@ -271,7 +271,7 @@
<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="UmPasswordDialog" swapped="yes"/>
<signal name="toggled" handler="action_now_radio_toggled_cb" object="CcPasswordDialog" swapped="yes"/>
</object>
<packing>
<property name="position">1</property>

View file

@ -42,7 +42,7 @@
#include "um-account-dialog.h"
#include "cc-language-chooser.h"
#include "um-password-dialog.h"
#include "cc-password-dialog.h"
#include "um-carousel.h"
#include "um-photo-dialog.h"
#include "um-fingerprint-dialog.h"
@ -1043,11 +1043,11 @@ static void
change_password (CcUserPanel *self)
{
ActUser *user;
UmPasswordDialog *dialog;
CcPasswordDialog *dialog;
GtkWindow *parent;
user = get_selected_user (self);
dialog = um_password_dialog_new (user);
dialog = cc_password_dialog_new (user);
parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);

View file

@ -101,6 +101,7 @@ common_sources = files(
)
resource_data = files(
'cc-password-dialog.ui',
'cc-user-panel.ui',
'data/icons/left-index-finger.png',
'data/icons/left-little-finger.png',
@ -121,7 +122,6 @@ resource_data = files(
'data/history-dialog.ui',
'data/join-dialog.ui',
'data/user-accounts-dialog.css',
'um-password-dialog.ui',
)
common_sources += gnome.compile_resources(
@ -145,13 +145,13 @@ common_sources += gnome.gdbus_codegen(
sources = common_sources + files(
'cc-crop-area.c',
'cc-password-dialog.c',
'cc-user-panel.c',
'run-passwd.c',
'um-account-type.c',
'um-carousel.c',
'um-fingerprint-dialog.c',
'um-history-dialog.c',
'um-password-dialog.c',
'um-photo-dialog.c',
'um-user-image.c',
)

View file

@ -1,532 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright 2009-2010 Red Hat, Inc,
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Written by: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <act/act.h>
#include "um-password-dialog.h"
#include "um-resources.h"
#include "um-utils.h"
#include "run-passwd.h"
#include "pw-utils.h"
#define PASSWORD_CHECK_TIMEOUT 600
struct _UmPasswordDialog
{
GtkDialog parent_instance;
GtkBox *action_radio_box;
GtkRadioButton *action_now_radio;
GtkRadioButton *action_login_radio;
GtkButton *ok_button;
GtkLabel *old_password_label;
GtkEntry *old_password_entry;
GtkEntry *password_entry;
GtkLabel *password_hint_label;
GtkLevelBar *strength_indicator;
GtkEntry *verify_entry;
GtkLabel *verify_hint_label;
gint password_entry_timeout_id;
ActUser *user;
ActUserPasswordMode password_mode;
gboolean old_password_ok;
gint old_password_entry_timeout_id;
PasswdHandler *passwd_handler;
};
G_DEFINE_TYPE (UmPasswordDialog, um_password_dialog, GTK_TYPE_DIALOG)
static gint
update_password_strength (UmPasswordDialog *um)
{
const gchar *password;
const gchar *old_password;
const gchar *username;
gint strength_level;
const gchar *hint;
const gchar *verify;
password = gtk_entry_get_text (um->password_entry);
old_password = gtk_entry_get_text (um->old_password_entry);
username = act_user_get_user_name (um->user);
pw_strength (password, old_password, username,
&hint, &strength_level);
gtk_level_bar_set_value (um->strength_indicator, strength_level);
gtk_label_set_label (um->password_hint_label, hint);
if (strength_level > 1) {
set_entry_validation_checkmark (um->password_entry);
} else if (strlen (password) == 0) {
set_entry_generation_icon (um->password_entry);
} else {
clear_entry_validation_error (um->password_entry);
}
verify = gtk_entry_get_text (um->verify_entry);
if (strlen (verify) == 0) {
gtk_widget_set_sensitive (GTK_WIDGET (um->verify_entry), strength_level > 1);
}
return strength_level;
}
static void
password_changed_cb (PasswdHandler *handler,
GError *error,
UmPasswordDialog *um)
{
GtkWidget *dialog;
const gchar *primary_text;
const gchar *secondary_text;
gtk_widget_set_sensitive (GTK_WIDGET (um), TRUE);
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (um)), NULL);
if (!error) {
gtk_dialog_response (GTK_DIALOG (um), GTK_RESPONSE_ACCEPT);
return;
}
if (error->code == PASSWD_ERROR_REJECTED) {
primary_text = error->message;
secondary_text = _("Please choose another password.");
gtk_entry_set_text (um->password_entry, "");
gtk_widget_grab_focus (GTK_WIDGET (um->password_entry));
gtk_entry_set_text (um->verify_entry, "");
}
else if (error->code == PASSWD_ERROR_AUTH_FAILED) {
primary_text = error->message;
secondary_text = _("Please type your current password again.");
gtk_entry_set_text (um->old_password_entry, "");
gtk_widget_grab_focus (GTK_WIDGET (um->old_password_entry));
}
else {
primary_text = _("Password could not be changed");
secondary_text = error->message;
}
dialog = gtk_message_dialog_new (GTK_WINDOW (um),
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s", primary_text);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", secondary_text);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
static void
ok_button_clicked_cb (UmPasswordDialog *um)
{
const gchar *password;
password = gtk_entry_get_text (um->password_entry);
switch (um->password_mode) {
case ACT_USER_PASSWORD_MODE_REGULAR:
if (act_user_get_uid (um->user) == getuid ()) {
GdkDisplay *display;
g_autoptr(GdkCursor) cursor = NULL;
/* When setting a password for the current user,
* use passwd directly, to preserve the audit trail
* and to e.g. update the keyring password.
*/
passwd_change_password (um->passwd_handler, password,
(PasswdCallback) password_changed_cb, um);
gtk_widget_set_sensitive (GTK_WIDGET (um), FALSE);
display = gtk_widget_get_display (GTK_WIDGET (um));
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (um)), cursor);
gdk_display_flush (display);
return;
}
act_user_set_password_mode (um->user, ACT_USER_PASSWORD_MODE_REGULAR);
act_user_set_password (um->user, password, "");
break;
case ACT_USER_PASSWORD_MODE_SET_AT_LOGIN:
act_user_set_password_mode (um->user, um->password_mode);
act_user_set_automatic_login (um->user, FALSE);
break;
default:
g_assert_not_reached ();
}
gtk_dialog_response (GTK_DIALOG (um), GTK_RESPONSE_ACCEPT);
}
static void
update_sensitivity (UmPasswordDialog *um)
{
const gchar *password, *verify;
gboolean can_change;
int strength;
password = gtk_entry_get_text (um->password_entry);
verify = gtk_entry_get_text (um->verify_entry);
if (um->password_mode == ACT_USER_PASSWORD_MODE_REGULAR) {
strength = update_password_strength (um);
can_change = strength > 1 && strcmp (password, verify) == 0 &&
(um->old_password_ok || !gtk_widget_get_visible (GTK_WIDGET (um->old_password_entry)));
}
else {
can_change = TRUE;
}
gtk_widget_set_sensitive (GTK_WIDGET (um->ok_button), can_change);
}
static void
mode_change (UmPasswordDialog *um,
ActUserPasswordMode mode)
{
gboolean active;
active = (mode == ACT_USER_PASSWORD_MODE_REGULAR);
gtk_widget_set_sensitive (GTK_WIDGET (um->password_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (um->verify_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (um->old_password_entry), active);
gtk_widget_set_sensitive (GTK_WIDGET (um->password_hint_label), active);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->action_now_radio), active);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->action_login_radio), !active);
um->password_mode = mode;
update_sensitivity (um);
}
static void
action_now_radio_toggled_cb (UmPasswordDialog *um)
{
gint active;
ActUserPasswordMode mode;
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (um->action_now_radio));
mode = active ? ACT_USER_PASSWORD_MODE_REGULAR : ACT_USER_PASSWORD_MODE_SET_AT_LOGIN;
mode_change (um, mode);
}
static void
update_password_match (UmPasswordDialog *um)
{
const gchar *password;
const gchar *verify;
const gchar *message = "";
password = gtk_entry_get_text (um->password_entry);
verify = gtk_entry_get_text (um->verify_entry);
if (strlen (verify) > 0) {
if (strcmp (password, verify) != 0) {
message = _("The passwords do not match.");
}
else {
set_entry_validation_checkmark (um->verify_entry);
}
}
gtk_label_set_label (um->verify_hint_label, message);
}
static gboolean
password_entry_timeout (UmPasswordDialog *um)
{
update_password_strength (um);
update_sensitivity (um);
update_password_match (um);
um->password_entry_timeout_id = 0;
return FALSE;
}
static void
recheck_password_match (UmPasswordDialog *um)
{
const gchar *password;
if (um->password_entry_timeout_id != 0) {
g_source_remove (um->password_entry_timeout_id);
um->password_entry_timeout_id = 0;
}
gtk_widget_set_sensitive (GTK_WIDGET (um->ok_button), FALSE);
password = gtk_entry_get_text (um->password_entry);
if (strlen (password) == 0) {
gtk_entry_set_visibility (um->password_entry, FALSE);
}
um->password_entry_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT,
(GSourceFunc) password_entry_timeout,
um);
}
static void
password_entry_changed (UmPasswordDialog *um)
{
clear_entry_validation_error (um->password_entry);
clear_entry_validation_error (um->verify_entry);
recheck_password_match (um);
}
static void
verify_entry_changed (UmPasswordDialog *um)
{
clear_entry_validation_error (um->verify_entry);
recheck_password_match (um);
}
static gboolean
password_entry_focus_out_cb (UmPasswordDialog *um)
{
if (um->password_entry_timeout_id != 0) {
g_source_remove (um->password_entry_timeout_id);
um->password_entry_timeout_id = 0;
}
password_entry_timeout (um);
return FALSE;
}
static gboolean
password_entry_key_press_cb (UmPasswordDialog *um,
GdkEvent *event)
{
GdkEventKey *key = (GdkEventKey *)event;
if (key->keyval == GDK_KEY_Tab)
password_entry_timeout (um);
return FALSE;
}
static void
auth_cb (PasswdHandler *handler,
GError *error,
UmPasswordDialog *um)
{
if (error) {
um->old_password_ok = FALSE;
}
else {
um->old_password_ok = TRUE;
set_entry_validation_checkmark (um->old_password_entry);
}
update_sensitivity (um);
}
static gboolean
old_password_entry_timeout (UmPasswordDialog *um)
{
const gchar *text;
update_sensitivity (um);
text = gtk_entry_get_text (um->old_password_entry);
if (!um->old_password_ok) {
passwd_authenticate (um->passwd_handler, text, (PasswdCallback)auth_cb, um);
}
um->old_password_entry_timeout_id = 0;
return FALSE;
}
static gboolean
old_password_entry_focus_out_cb (UmPasswordDialog *um)
{
if (um->old_password_entry_timeout_id != 0) {
g_source_remove (um->old_password_entry_timeout_id);
um->old_password_entry_timeout_id = 0;
}
old_password_entry_timeout (um);
return FALSE;
}
static void
old_password_entry_changed (UmPasswordDialog *um)
{
if (um->old_password_entry_timeout_id != 0) {
g_source_remove (um->old_password_entry_timeout_id);
um->old_password_entry_timeout_id = 0;
}
clear_entry_validation_error (um->old_password_entry);
gtk_widget_set_sensitive (GTK_WIDGET (um->ok_button), FALSE);
um->old_password_ok = FALSE;
um->old_password_entry_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT,
(GSourceFunc) old_password_entry_timeout,
um);
}
static void
password_entry_icon_press_cb (UmPasswordDialog *um)
{
g_autofree gchar *pwd = NULL;
pwd = pw_generate ();
if (pwd == NULL)
return;
gtk_entry_set_text (um->password_entry, pwd);
gtk_entry_set_text (um->verify_entry, pwd);
gtk_entry_set_visibility (um->password_entry, TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (um->verify_entry), TRUE);
}
static void
um_password_dialog_dispose (GObject *object)
{
UmPasswordDialog *um = UM_PASSWORD_DIALOG (object);
g_clear_object (&um->user);
if (um->passwd_handler) {
passwd_destroy (um->passwd_handler);
um->passwd_handler = NULL;
}
if (um->old_password_entry_timeout_id != 0) {
g_source_remove (um->old_password_entry_timeout_id);
um->old_password_entry_timeout_id = 0;
}
if (um->password_entry_timeout_id != 0) {
g_source_remove (um->password_entry_timeout_id);
um->password_entry_timeout_id = 0;
}
G_OBJECT_CLASS (um_password_dialog_parent_class)->dispose (object);
}
static void
um_password_dialog_class_init (UmPasswordDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = um_password_dialog_dispose;
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/user-accounts/um-password-dialog.ui");
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, action_radio_box);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, action_now_radio);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, action_login_radio);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, ok_button);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, old_password_label);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, old_password_entry);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, password_entry);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, password_hint_label);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, strength_indicator);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, verify_entry);
gtk_widget_class_bind_template_child (widget_class, UmPasswordDialog, verify_hint_label);
gtk_widget_class_bind_template_callback (widget_class, action_now_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);
gtk_widget_class_bind_template_callback (widget_class, password_entry_changed);
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_entry_timeout);
gtk_widget_class_bind_template_callback (widget_class, verify_entry_changed);
}
static void
um_password_dialog_init (UmPasswordDialog *um)
{
g_resources_register (um_get_resource ());
gtk_widget_init_template (GTK_WIDGET (um));
}
UmPasswordDialog *
um_password_dialog_new (ActUser *user)
{
UmPasswordDialog *um;
g_return_val_if_fail (ACT_IS_USER (user), NULL);
um = g_object_new (UM_TYPE_PASSWORD_DIALOG,
"use-header-bar", 1,
NULL);
um->user = g_object_ref (user);
if (act_user_get_uid (um->user) == getuid ()) {
gboolean visible;
mode_change (um, ACT_USER_PASSWORD_MODE_REGULAR);
gtk_widget_hide (GTK_WIDGET (um->action_radio_box));
visible = (act_user_get_password_mode (user) != ACT_USER_PASSWORD_MODE_NONE);
gtk_widget_set_visible (GTK_WIDGET (um->old_password_label), visible);
gtk_widget_set_visible (GTK_WIDGET (um->old_password_entry), visible);
um->old_password_ok = !visible;
um->passwd_handler = passwd_init ();
}
else {
mode_change (um, ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
gtk_widget_show (GTK_WIDGET (um->action_radio_box));
gtk_widget_hide (GTK_WIDGET (um->old_password_label));
gtk_widget_hide (GTK_WIDGET (um->old_password_entry));
um->old_password_ok = TRUE;
}
if (um->old_password_ok == FALSE)
gtk_widget_grab_focus (GTK_WIDGET (um->old_password_entry));
else
gtk_widget_grab_focus (GTK_WIDGET (um->password_entry));
gtk_widget_grab_default (GTK_WIDGET (um->ok_button));
return um;
}

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/control-center/user-accounts">
<file preprocess="xml-stripblanks">cc-password-dialog.ui</file>
<file preprocess="xml-stripblanks">cc-user-panel.ui</file>
<file alias="account-dialog.ui" preprocess="xml-stripblanks">data/account-dialog.ui</file>
<file alias="avatar-chooser.ui" preprocess="xml-stripblanks">data/avatar-chooser.ui</file>
@ -22,6 +23,5 @@
<file alias="right-little-finger.png">data/icons/right-little-finger.png</file>
<file alias="right-ring-finger.png">data/icons/right-ring-finger.png</file>
<file alias="right-thumb.png">data/icons/right-thumb.png</file>
<file preprocess="xml-stripblanks">um-password-dialog.ui</file>
</gresource>
</gresources>

View file

@ -193,6 +193,8 @@ panels/universal-access/gnome-universal-access-panel.desktop.in.in
panels/universal-access/uap.ui
panels/universal-access/zoom-options.c
panels/universal-access/zoom-options.ui
panels/user-accounts/cc-password-dialog.c
panels/user-accounts/cc-password-dialog.ui
panels/user-accounts/cc-user-panel.c
panels/user-accounts/cc-user-panel.ui
panels/user-accounts/data/account-dialog.ui
@ -208,8 +210,6 @@ panels/user-accounts/um-account-dialog.c
panels/user-accounts/um-account-type.c
panels/user-accounts/um-fingerprint-dialog.c
panels/user-accounts/um-history-dialog.c
panels/user-accounts/um-password-dialog.c
panels/user-accounts/um-password-dialog.ui
panels/user-accounts/um-photo-dialog.c
panels/user-accounts/um-realm-manager.c
panels/user-accounts/um-utils.c