[gnome-control-center] user-accounts: fix enterprise accounts deleting
- From: Ondrej Holy <oholy src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] user-accounts: fix enterprise accounts deleting
- Date: Mon, 3 Nov 2014 17:13:51 +0000 (UTC)
commit 5790368643487778d7b7cfb40d082d0f912189f0
Author: Ondrej Holy <oholy redhat com>
Date: Tue Sep 30 11:08:08 2014 +0200
user-accounts: fix enterprise accounts deleting
Deleting enterprise accounts using act_user_manager_delete_user fails
with error: userdel failed, because enterprise accounts are added
using act_user_manager_cache_user and don't have entries in passwd
file. Thus enterprise accounts should be removed by
act_user_manager_uncache_user.
https://bugzilla.gnome.org/show_bug.cgi?id=727871
panels/user-accounts/um-user-panel.c | 217 +++++++++++++++++++++++++++++++++-
1 files changed, 212 insertions(+), 5 deletions(-)
---
diff --git a/panels/user-accounts/um-user-panel.c b/panels/user-accounts/um-user-panel.c
index a236193..f3a929f 100644
--- a/panels/user-accounts/um-user-panel.c
+++ b/panels/user-accounts/um-user-panel.c
@@ -58,6 +58,8 @@
#include "cc-common-language.h"
+#include "um-realm-manager.h"
+
#define USER_ACCOUNTS_PERMISSION "org.gnome.controlcenter.user-accounts.administration"
CC_PANEL_REGISTER (CcUserPanel, cc_user_panel)
@@ -67,6 +69,7 @@ CC_PANEL_REGISTER (CcUserPanel, cc_user_panel)
struct _CcUserPanelPrivate {
ActUserManager *um;
+ GCancellable *cancellable;
GtkBuilder *builder;
GtkWidget *notification;
@@ -101,6 +104,21 @@ enum {
NUM_USER_LIST_COLS
};
+typedef struct {
+ CcUserPanel *self;
+ GCancellable *cancellable;
+ gchar *login;
+} AsyncDeleteData;
+
+static void
+async_delete_data_free (AsyncDeleteData *data)
+{
+ g_object_unref (data->self);
+ g_object_unref (data->cancellable);
+ g_free (data->login);
+ g_slice_free (AsyncDeleteData, data);
+}
+
static void
show_error_dialog (CcUserPanelPrivate *d,
const gchar *message,
@@ -476,8 +494,174 @@ delete_user_response (GtkWidget *dialog,
}
static void
-delete_user (GtkButton *button, CcUserPanelPrivate *d)
+enterprise_user_revoked (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AsyncDeleteData *data = user_data;
+ CcUserPanelPrivate *d = data->self->priv;
+ UmRealmCommon *common = UM_REALM_COMMON (source);
+ GError *error = NULL;
+
+ if (g_cancellable_is_cancelled (data->cancellable)) {
+ async_delete_data_free (data);
+ return;
+ }
+
+ um_realm_common_call_change_login_policy_finish (common, result, &error);
+ if (error != NULL) {
+ show_error_dialog (d, _("Failed to revoke remotely managed user"), error);
+ g_error_free (error);
+ }
+
+ async_delete_data_free (data);
+}
+
+static UmRealmCommon *
+find_matching_realm (UmRealmManager *realm_manager, const gchar *login)
+{
+ UmRealmCommon *common = NULL;
+ GList *realms, *l;
+
+ realms = um_realm_manager_get_realms (realm_manager);
+ for (l = realms; l != NULL; l = g_list_next (l)) {
+ const gchar * const *permitted_logins;
+ gint i;
+
+ common = um_realm_object_get_common (l->data);
+ permitted_logins = um_realm_common_get_permitted_logins (common);
+ for (i = 0; permitted_logins[i] != NULL; i++) {
+ if (g_strcmp0 (permitted_logins[i], login) == 0)
+ break;
+ }
+
+ if (permitted_logins[i] != NULL)
+ break;
+
+ g_clear_object (&common);
+ }
+ g_list_free_full (realms, g_object_unref);
+
+ return common;
+}
+
+static void
+realm_manager_found (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AsyncDeleteData *data = user_data;
+ CcUserPanelPrivate *d = data->self->priv;
+ UmRealmCommon *common;
+ UmRealmManager *realm_manager;
+ const gchar *add[1];
+ const gchar *remove[2];
+ GVariant *options;
+ GError *error = NULL;
+
+ if (g_cancellable_is_cancelled (data->cancellable)) {
+ async_delete_data_free (data);
+ return;
+ }
+
+ realm_manager = um_realm_manager_new_finish (result, &error);
+ if (error != NULL) {
+ show_error_dialog (d, _("Failed to revoke remotely managed user"), error);
+ g_error_free (error);
+ async_delete_data_free (data);
+ return;
+ }
+
+ /* Find matching realm */
+ common = find_matching_realm (realm_manager, data->login);
+ if (common == NULL) {
+ /* The realm was probably left */
+ async_delete_data_free (data);
+ return;
+ }
+
+ /* Remove the user from permitted logins */
+ g_debug ("Denying future login for: %s", data->login);
+
+ add[0] = NULL;
+ remove[0] = data->login;
+ remove[1] = NULL;
+
+ options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+ um_realm_common_call_change_login_policy (common, "",
+ add, remove, options,
+ data->cancellable,
+ enterprise_user_revoked,
+ data);
+
+ g_object_unref (common);
+}
+
+static void
+enterprise_user_uncached (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncDeleteData *data = user_data;
+ CcUserPanelPrivate *d = data->self->priv;
+ ActUserManager *manager = ACT_USER_MANAGER (source);
+ GError *error = NULL;
+
+ if (g_cancellable_is_cancelled (data->cancellable)) {
+ async_delete_data_free (data);
+ return;
+ }
+
+ act_user_manager_uncache_user_finish (manager, res, &error);
+ if (error == NULL) {
+ /* Find realm manager */
+ um_realm_manager_new (d->cancellable, realm_manager_found, data);
+ }
+ else {
+ show_error_dialog (d, _("Failed to revoke remotely managed user"), error);
+ g_error_free (error);
+ async_delete_data_free (data);
+ }
+}
+
+static void
+delete_enterprise_user_response (GtkWidget *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ CcUserPanel *self = UM_USER_PANEL (user_data);
+ CcUserPanelPrivate *d = self->priv;
+ AsyncDeleteData *data;
+ ActUser *user;
+
+ gtk_widget_destroy (dialog);
+
+ if (response_id != GTK_RESPONSE_ACCEPT) {
+ return;
+ }
+
+ user = get_selected_user (self->priv);
+
+ data = g_slice_new (AsyncDeleteData);
+ data->self = g_object_ref (self);
+ data->cancellable = g_object_ref (d->cancellable);
+ data->login = g_strdup (act_user_get_user_name (user));
+
+ g_object_unref (user);
+
+ /* Uncache the user account from the accountsservice */
+ g_debug ("Uncaching remote user: %s", data->login);
+
+ act_user_manager_uncache_user_async (d->um, data->login,
+ data->cancellable,
+ enterprise_user_uncached,
+ data);
+}
+
+static void
+delete_user (GtkButton *button, CcUserPanel *self)
{
+ CcUserPanelPrivate *d = self->priv;
ActUser *user;
GtkWidget *dialog;
@@ -507,7 +691,7 @@ delete_user (GtkButton *button, CcUserPanelPrivate *d)
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
}
- else {
+ else if (act_user_is_local_account (user)) {
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
0,
GTK_MESSAGE_QUESTION,
@@ -529,6 +713,24 @@ delete_user (GtkButton *button, CcUserPanelPrivate *d)
g_signal_connect (dialog, "response",
G_CALLBACK (delete_user_response), d);
}
+ else {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
+ 0,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("Are you sure you want to revoke remotely managed %s's
account?"),
+ get_real_or_user_name (user));
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ _("_Delete"), GTK_RESPONSE_ACCEPT,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ NULL);
+
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "system-users");
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (delete_enterprise_user_response), self);
+ }
g_signal_connect (dialog, "close",
G_CALLBACK (gtk_widget_destroy), NULL);
@@ -1344,8 +1546,9 @@ update_padding (GtkWidget *button, GtkWidget *label)
}
static void
-setup_main_window (CcUserPanelPrivate *d)
+setup_main_window (CcUserPanel *self)
{
+ CcUserPanelPrivate *d = self->priv;
GtkWidget *userlist;
GtkTreeModel *model;
GtkListStore *store;
@@ -1423,7 +1626,7 @@ setup_main_window (CcUserPanelPrivate *d)
g_signal_connect (button, "clicked", G_CALLBACK (add_user), d);
button = get_widget (d, "remove-user-toolbutton");
- g_signal_connect (button, "clicked", G_CALLBACK (delete_user), d);
+ g_signal_connect (button, "clicked", G_CALLBACK (delete_user), self);
button = get_widget (d, "user-icon-nonbutton");
add_unlock_tooltip (button);
@@ -1506,6 +1709,7 @@ cc_user_panel_init (CcUserPanel *self)
d->builder = gtk_builder_new ();
d->um = act_user_manager_get_default ();
+ d->cancellable = g_cancellable_new ();
error = NULL;
if (!gtk_builder_add_from_resource (d->builder,
@@ -1522,7 +1726,7 @@ cc_user_panel_init (CcUserPanel *self)
d->main_box = get_widget (d, "accounts-vbox");
gtk_container_add (GTK_CONTAINER (self), get_widget (d, "overlay"));
d->history_dialog = um_history_dialog_new ();
- setup_main_window (d);
+ setup_main_window (self);
context = gtk_widget_get_style_context (get_widget (d, "list-scrolledwindow"));
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
@@ -1535,6 +1739,9 @@ cc_user_panel_dispose (GObject *object)
{
CcUserPanelPrivate *priv = UM_USER_PANEL (object)->priv;
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
+
if (priv->um) {
g_signal_handlers_disconnect_by_data (priv->um, priv);
priv->um = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]