[gnome-control-center/wip/identity: 7/11] user-accounts: Use identity manager in user panel



commit 53f91662b28fadc8ff63ee5c0c5dd731ff1fde5a
Author: Ray Strode <rstrode redhat com>
Date:   Wed Feb 29 13:43:42 2012 -0500

    user-accounts: Use identity manager in user panel
    
    This commit hooks up the identity manager to the actual
    UI.  It creates a list of currently "accessible realms"
    and provides buttons for signing out of those realms.
    
    This is outlined here:
    
    https://live.gnome.org/Design/Proposals/UserIdentities
    
    https://bugzilla.gnome.org/show_bug.cgi?id=671156

 panels/user-accounts/data/user-accounts-dialog.ui |   24 +-
 panels/user-accounts/um-user-panel.c              |  404 ++++++++++++++++++++-
 2 files changed, 413 insertions(+), 15 deletions(-)
---
diff --git a/panels/user-accounts/data/user-accounts-dialog.ui b/panels/user-accounts/data/user-accounts-dialog.ui
index 0c37fd6..264ee6a 100644
--- a/panels/user-accounts/data/user-accounts-dialog.ui
+++ b/panels/user-accounts/data/user-accounts-dialog.ui
@@ -298,6 +298,24 @@
                           </packing>
                         </child>
                         <child>
+                          <object class="GtkLabel" id="accessible-realms-label">
+                            <property name="visible">True</property>
+                            <property name="xalign">1</property>
+                            <property name="halign">GTK_ALIGN_END</property>
+                            <property name="hexpand">TRUE</property>
+                            <property name="label" translatable="yes">Accessible Realms</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="top_attach">7</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
                           <object class="GtkLabel" id="autologin-label">
                             <property name="visible">True</property>
                             <property name="xalign">1</property>
@@ -313,7 +331,7 @@
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="width">1</property>
-                            <property name="top_attach">7</property>
+                            <property name="top_attach">8</property>
                             <property name="height">1</property>
                           </packing>
                         </child>
@@ -337,7 +355,7 @@
                           <packing>
                             <property name="left_attach">2</property>
                             <property name="width">1</property>
-                            <property name="top_attach">7</property>
+                            <property name="top_attach">8</property>
                             <property name="height">1</property>
                           </packing>
                         </child>
@@ -357,7 +375,7 @@
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="width">1</property>
-                            <property name="top_attach">8</property>
+                            <property name="top_attach">9</property>
                             <property name="height">1</property>
                           </packing>
                         </child>
diff --git a/panels/user-accounts/um-user-panel.c b/panels/user-accounts/um-user-panel.c
index 52e1af9..63602a3 100644
--- a/panels/user-accounts/um-user-panel.c
+++ b/panels/user-accounts/um-user-panel.c
@@ -41,8 +41,14 @@
 
 #include "um-user.h"
 #include "um-user-manager.h"
+#include "um-identity-manager.h"
+
+#ifdef HAVE_KERBEROS
+#include "um-kerberos-identity-manager.h"
+#endif
 
 #include "cc-strength-bar.h"
+
 #include "um-editable-button.h"
 #include "um-editable-combo.h"
 
@@ -62,6 +68,15 @@ G_DEFINE_DYNAMIC_TYPE (UmUserPanel, um_user_panel, CC_TYPE_PANEL)
 #define UM_USER_PANEL_PRIVATE(o) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), UM_TYPE_USER_PANEL, UmUserPanelPrivate))
 
+typedef struct {
+        UmUserPanelPrivate *d;
+        char *identifier;
+        UmIdentity *identity;
+        GtkWidget *box;
+        GtkWidget *label;
+        GtkWidget *button;
+} Realm;
+
 struct _UmUserPanelPrivate {
         UmUserManager *um;
         GtkBuilder *builder;
@@ -70,6 +85,8 @@ struct _UmUserPanelPrivate {
         GPermission *permission;
         GtkWidget *language_chooser;
 
+        GHashTable *accessible_realms;
+        UmIdentityManager *identity_manager;
         UmAccountDialog *account_dialog;
         UmPasswordDialog *password_dialog;
         UmPhotoDialog *photo_dialog;
@@ -399,12 +416,8 @@ delete_user_response (GtkWidget         *dialog,
 
         user = get_selected_user (d);
 
-        um_user_manager_delete_user (d->um,
-                                     user,
-                                     remove_files,
-                                     (GAsyncReadyCallback)delete_user_done,
-                                     d,
-                                     NULL);
+        um_user_manager_delete_user (d->um, user, remove_files,
+                                     (GAsyncReadyCallback) delete_user_done, d, NULL);
 
         g_object_unref (user);
 }
@@ -557,6 +570,87 @@ autologin_changed (GObject            *object,
         g_object_unref (user);
 }
 
+#ifdef HAVE_KERBEROS
+static void
+get_position_of_accessible_realms_label (UmUserPanelPrivate *d,
+                                         int                *left_position,
+                                         int                *top_position)
+{
+
+        GtkWidget *grid, *label;
+
+        grid = get_widget (d, "user-grid");
+        label = get_widget (d, "accessible-realms-label");
+        gtk_container_child_get (GTK_CONTAINER (grid),
+                                 label,
+                                 "left-attach", left_position,
+                                 "top-attach", top_position,
+                                 NULL);
+}
+
+static void
+get_position_of_next_realm_box (UmUserPanelPrivate *d,
+                                 int                *left_position,
+                                 int                *top_position)
+{
+        GtkWidget *grid;
+
+        GHashTableIter iter;
+        gpointer key, value;
+
+        grid = get_widget (d, "user-grid");
+        get_position_of_accessible_realms_label (d, left_position, top_position);
+        *left_position += 1;
+
+        g_hash_table_iter_init (&iter, d->accessible_realms);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                int other_realm_top_position;
+                Realm *realm = value;
+
+                gtk_container_child_get (GTK_CONTAINER (grid),
+                                         realm->box,
+                                         "top-attach", &other_realm_top_position,
+                                         NULL);
+
+                *top_position = MAX (*top_position, other_realm_top_position + 1);
+        }
+}
+
+static void
+update_accessible_realms_visiblity (UmUserPanelPrivate *d)
+{
+        GtkWidget *label;
+        GHashTableIter iter;
+        gpointer key, value;
+        UmUser    *user;
+        uid_t      uid;
+        gboolean should_show;
+
+        label = get_widget (d, "accessible-realms-label");
+        user = get_selected_user (d);
+        uid = um_user_get_uid (user);
+
+        if (g_hash_table_size (d->accessible_realms) > 0 && uid == geteuid ()) {
+                should_show = TRUE;
+        } else {
+                should_show = FALSE;
+        }
+
+        gtk_widget_set_visible (label, should_show);
+        g_hash_table_iter_init (&iter, d->accessible_realms);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                Realm *realm = value;
+
+                gtk_widget_set_visible (realm->box, should_show);
+        }
+}
+#else /* HAVE_KERBEROS */
+static void
+update_accessible_realms_visiblity (UmUserPanelPrivate *d)
+{
+}
+#endif /* HAVE_KERBEROS */
+
 static void
 show_user (UmUser *user, UmUserPanelPrivate *d)
 {
@@ -634,9 +728,11 @@ show_user (UmUser *user, UmUserPanelPrivate *d)
                         gtk_widget_hide (widget);
                 }
         }
+
+        update_accessible_realms_visiblity (d);
 }
 
-static void on_permission_changed (GPermission *permission, GParamSpec *pspec, gpointer data);
+static void on_permission_changed (GPermission *permission, GParamSpec *pspec, UmUserPanelPrivate *d);
 
 static void
 selected_user_changed (GtkTreeSelection *selection, UmUserPanelPrivate *d)
@@ -1000,11 +1096,10 @@ show_administrative_tasks (UmUserPanelPrivate *d)
 }
 
 static void
-on_permission_changed (GPermission *permission,
-                       GParamSpec  *pspec,
-                       gpointer     data)
+on_permission_changed (GPermission        *permission,
+                       GParamSpec         *pspec,
+                       UmUserPanelPrivate *d)
 {
-        UmUserPanelPrivate *d = data;
         gboolean is_authorized;
         gboolean self_selected;
         UmUser *user;
@@ -1347,6 +1442,280 @@ setup_main_window (UmUserPanelPrivate *d)
         g_object_unref (icon);
 }
 
+#ifdef HAVE_KERBEROS
+static void
+remove_accessible_realm_for_identity (UmUserPanelPrivate *d,
+                                      UmIdentity         *identity)
+{
+        GtkWidget *grid;
+        Realm *realm;
+        GHashTableIter iter;
+        gpointer key, value;
+        int top_position;
+
+        realm = g_hash_table_lookup (d->accessible_realms,
+                                     (gpointer)
+                                     um_identity_get_identifier (identity));
+
+        if (realm == NULL) {
+                return;
+        }
+
+        grid = get_widget (d, "user-grid");
+
+        gtk_container_child_get (GTK_CONTAINER (grid),
+                                 realm->box,
+                                 "top-attach", &top_position,
+                                 NULL);
+
+        g_hash_table_remove (d->accessible_realms, realm->identifier);
+
+        g_hash_table_iter_init (&iter, d->accessible_realms);
+        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                int other_realm_top_position;
+
+                realm = value;
+
+                gtk_container_child_get (GTK_CONTAINER (grid),
+                                         realm->box,
+                                         "top-attach", &other_realm_top_position,
+                                         NULL);
+
+                if (other_realm_top_position > top_position) {
+                        other_realm_top_position--;
+                        gtk_container_child_set (GTK_CONTAINER (grid),
+                                                 realm->box,
+                                                 "top-attach", other_realm_top_position,
+                                                 NULL);
+                }
+        }
+        update_accessible_realms_visiblity (d);
+}
+
+static void
+rename_accessible_realm_for_identity (UmUserPanelPrivate *d,
+                                      UmIdentity         *identity)
+{
+        Realm *realm;
+        char *name;
+
+        realm = g_hash_table_lookup (d->accessible_realms,
+                                     (gpointer)
+                                     um_identity_get_identifier (identity));
+
+        if (realm == NULL) {
+                return;
+        }
+
+        name = um_identity_manager_name_identity (d->identity_manager,
+                                                  identity);
+        gtk_label_set_text (GTK_LABEL (realm->label), name);
+        g_free (name);
+}
+
+static void
+on_signed_out (UmIdentityManager *manager,
+               GAsyncResult      *result,
+               gpointer           user_data)
+{
+        UmIdentity *identity = UM_IDENTITY (user_data);
+
+        um_identity_manager_sign_identity_out_finish (manager,
+                                                      result,
+                                                      NULL);
+        g_object_unref (identity);
+}
+
+static void
+on_sign_out_clicked (GtkButton          *button,
+                     Realm              *realm)
+{
+        UmUserPanelPrivate *d = realm->d;
+
+        um_identity_manager_sign_identity_out (d->identity_manager, realm->identity, NULL,
+                                               (GAsyncReadyCallback) on_signed_out,
+                                               g_object_ref (realm->identity));
+}
+
+static Realm *
+realm_new (UmUserPanelPrivate *d,
+           UmIdentity         *identity)
+{
+        Realm *realm;
+        char *name;
+
+        realm = g_slice_new (Realm);
+        realm->d = d;
+        realm->identifier = g_strdup (um_identity_get_identifier (identity));
+        realm->identity = identity;
+        realm->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+        name = um_identity_manager_name_identity (d->identity_manager,
+                                                  identity);
+        realm->label = gtk_label_new (name);
+        g_free (name);
+
+        gtk_container_add (GTK_CONTAINER (realm->box), realm->label);
+
+        realm->button = gtk_button_new_with_label (_("Sign Out"));
+        gtk_widget_set_halign (GTK_WIDGET (realm->button),
+                               GTK_ALIGN_END);
+        gtk_widget_set_hexpand (GTK_WIDGET (realm->button),
+                                TRUE);
+
+        g_signal_connect (G_OBJECT (realm->button),
+                          "clicked",
+                          G_CALLBACK (on_sign_out_clicked),
+                          realm);
+        gtk_container_add (GTK_CONTAINER (realm->box), realm->button);
+        gtk_widget_show_all (realm->box);
+
+        return realm;
+}
+
+static void
+realm_free (Realm *realm)
+{
+        gtk_widget_destroy (realm->box);
+        g_free (realm->identifier);
+        g_slice_free (Realm, realm);
+}
+
+static void
+add_accessible_realm_for_identity (UmUserPanelPrivate *d,
+                                   UmIdentity         *identity)
+{
+        Realm *realm;
+        GtkWidget *grid;
+        int left_position, top_position;
+
+        remove_accessible_realm_for_identity (d, identity);
+
+        realm = realm_new (d, identity);
+
+        grid = get_widget (d, "user-grid");
+
+        get_position_of_next_realm_box (d, &left_position, &top_position);
+        g_hash_table_replace (d->accessible_realms,
+                              realm->identifier,
+                              realm);
+
+        gtk_grid_attach (GTK_GRID (grid),
+                         realm->box,
+                         left_position,
+                         top_position,
+                         1,
+                         1);
+        update_accessible_realms_visiblity (d);
+}
+
+static void
+on_identity_added (UmIdentityManager  *manager,
+                   UmIdentity         *identity,
+                   UmUserPanelPrivate *d)
+{
+        add_accessible_realm_for_identity (d, identity);
+}
+
+static void
+on_identity_renewed (UmIdentityManager  *manager,
+                     UmIdentity         *identity,
+                     UmUserPanelPrivate *d)
+{
+        add_accessible_realm_for_identity (d, identity);
+}
+
+static void
+on_identity_removed (UmIdentityManager  *manager,
+                     UmIdentity         *identity,
+                     UmUserPanelPrivate *d)
+{
+        remove_accessible_realm_for_identity (d, identity);
+}
+
+static void
+on_identity_expired (UmIdentityManager  *manager,
+                     UmIdentity         *identity,
+                     UmUserPanelPrivate *d)
+{
+        remove_accessible_realm_for_identity (d, identity);
+}
+
+static void
+on_identity_renamed (UmIdentityManager  *manager,
+                     UmIdentity         *identity,
+                     UmUserPanelPrivate *d)
+{
+        rename_accessible_realm_for_identity (d, identity);
+}
+
+static void
+on_identities_listed (UmIdentityManager  *manager,
+                      GAsyncResult       *result,
+                      UmUserPanelPrivate *d)
+{
+        GError *error = NULL;
+        GList *identities, *node;
+
+        g_signal_connect (manager,
+                          "identity-added",
+                          G_CALLBACK (on_identity_added),
+                          d);
+
+        g_signal_connect (manager,
+                          "identity-removed",
+                          G_CALLBACK (on_identity_removed),
+                          d);
+
+        g_signal_connect (manager,
+                          "identity-expired",
+                          G_CALLBACK (on_identity_expired),
+                          d);
+
+        g_signal_connect (manager,
+                          "identity-renewed",
+                          G_CALLBACK (on_identity_renewed),
+                          d);
+        g_signal_connect (manager,
+                          "identity-renamed",
+                          G_CALLBACK (on_identity_renamed),
+                          d);
+
+        identities = um_identity_manager_list_identities_finish (manager,
+                                                                 result,
+                                                                 &error);
+
+        if (identities == NULL) {
+                if (error != NULL) {
+                        g_warning ("UmUserPanel: Could not list identities: %s",
+                                   error->message);
+                        g_error_free (error);
+                }
+                return;
+        }
+
+	for (node = identities; node != NULL; node = node->next) {
+                UmIdentity *identity = node->data;
+
+                if (um_identity_is_signed_in (identity))
+                        add_accessible_realm_for_identity (d, identity);
+        }
+}
+#endif /* HAVE_KERBEROS */
+
+static void
+setup_realms (UmUserPanelPrivate *d)
+{
+#ifdef HAVE_KERBEROS
+        d->accessible_realms = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                      NULL, (GDestroyNotify) realm_free);
+
+        d->identity_manager = um_kerberos_identity_manager_new ();
+        um_identity_manager_list_identities (d->identity_manager, NULL,
+                                             (GAsyncReadyCallback) on_identities_listed, d);
+#endif
+}
+
 static void
 um_user_panel_init (UmUserPanel *self)
 {
@@ -1380,7 +1749,7 @@ um_user_panel_init (UmUserPanel *self)
                 g_error_free (error);
                 return;
         }
-
+        setup_realms (d);
         setup_main_window (d);
         d->account_dialog = um_account_dialog_new ();
         d->password_dialog = um_password_dialog_new ();
@@ -1428,6 +1797,17 @@ um_user_panel_dispose (GObject *object)
                 g_object_unref (priv->permission);
                 priv->permission = NULL;
         }
+
+        if (priv->accessible_realms) {
+                g_hash_table_unref (priv->accessible_realms);
+                priv->accessible_realms = NULL;
+        }
+
+        if (priv->identity_manager) {
+                g_object_unref (priv->identity_manager);
+                priv->identity_manager = NULL;
+        }
+
         G_OBJECT_CLASS (um_user_panel_parent_class)->dispose (object);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]