[accounts-dialog] Hide buttons when not allowed to make changes



commit d5fdd6d5ade84e971445fc588da46bf5ad5ad834
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jan 15 02:08:26 2010 -0500

    Hide buttons when not allowed to make changes
    
    This requires to use polkit in the dialog. Also, add some
    size groups to keep ui elements from moving around as buttons
    appear and disappear.

 configure.ac                 |    1 +
 data/user-accounts-dialog.ui |   54 ++++++++--
 src/Makefile.am              |    2 +
 src/main.c                   |  241 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 290 insertions(+), 8 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c3838c7..0e79382 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,7 @@ PKG_CHECK_MODULES(GTK, gtk+-2.0)
 PKG_CHECK_MODULES(GNOME_DESKTOP, gnome-desktop-2.0)
 PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1)
 PKG_CHECK_MODULES(UNIQUE, unique-1.0)
+PKG_CHECK_MODULES(POLKIT, polkit-gobject-1)
 
 AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX],["`$PKG_CONFIG --variable=prefix iso-codes`"],[ISO codes prefix])
 ISO_CODES=iso-codes
diff --git a/data/user-accounts-dialog.ui b/data/user-accounts-dialog.ui
index 0c52e6f..63e424b 100644
--- a/data/user-accounts-dialog.ui
+++ b/data/user-accounts-dialog.ui
@@ -36,7 +36,7 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkHBox" id="hbuttonbox1">
+                      <object class="GtkHBox" id="add-delete-buttonbox">
                         <property name="visible">True</property>
                         <property name="homogeneous">True</property>
                         <child>
@@ -433,7 +433,7 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="account-password-label">
+                              <object class="GtkLabel" id="password-label">
                                 <property name="visible">True</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Password:</property>
@@ -460,7 +460,7 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="account-email-label">
+                              <object class="GtkLabel" id="email-label">
                                 <property name="visible">True</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">E-mail address:</property>
@@ -487,7 +487,7 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="account-language-label">
+                              <object class="GtkLabel" id="language-label">
                                 <property name="visible">True</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Language:</property>
@@ -514,7 +514,7 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="account-location-label">
+                              <object class="GtkLabel" id="location-label">
                                 <property name="visible">True</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Location:</property>
@@ -552,13 +552,31 @@
                                   </object>
                                 </child>
                                 <child>
+                                  <object class="GtkAlignment" id="user-icon-nonbutton">
+                                    <property name="visible">False</property>
+                                    <property name="xscale">0</property>
+                                    <property name="yscale">0</property>
+                                    <child>
+                                      <object class="GtkImage" id="user-icon-image">
+                                        <property name="visible">True</property>
+                                        <property name="icon_size">6</property>
+                                        <property name="icon_name">stock_person</property>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                  </packing>
+                                </child>
+                                <child>
                                   <object class="GtkButton" id="user-icon-button">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="receives_default">True</property>
                                     <property name="tooltip-text" translatable="yes">Select personal image</property>
                                     <child>
-                                      <object class="GtkImage" id="user-icon-image">
+                                      <object class="GtkImage" id="user-icon-image2">
                                         <property name="visible">True</property>
                                         <property name="icon_size">6</property>
                                         <property name="icon_name">stock_person</property>
@@ -568,7 +586,6 @@
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">1</property>
                                   </packing>
                                 </child>
                               </object>
@@ -818,4 +835,27 @@
       </object>
     </child>
   </object>
+  <object class="GtkSizeGroup" id="user-icon-sizegroup">
+    <property name="mode">GTK_SIZE_GROUP_BOTH</property>
+    <widgets>
+      <widget name="user-icon-nonbutton"/>
+      <widget name="user-icon-button"/>
+    </widgets>
+  </object>
+  <object class="GtkSizeGroup" id="button-height-sizegroup">
+    <property name="mode">GTK_SIZE_GROUP_VERTICAL</property>
+    <widgets>
+      <widget name="change-name-button"/>
+      <widget name="change-account-type-button"/>
+      <widget name="change-password-button"/>
+      <widget name="change-email-button"/>
+      <widget name="change-language-button"/>
+      <widget name="change-location-button"/>
+      <widget name="account-type-label"/>
+      <widget name="password-label"/>
+      <widget name="email-label"/>
+      <widget name="language-label"/>
+      <widget name="location-label"/>
+    </widgets>
+  </object>
 </interface>
diff --git a/src/Makefile.am b/src/Makefile.am
index 3796bb1..fee1893 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ INCLUDES = \
 	$(GTK_CFLAGS)					\
 	$(GNOME_DESKTOP_CFLAGS) 			\
 	$(UNIQUE_CFLAGS)				\
+	$(POLKIT_CFLAGS)				\
 	$(WARN_CFLAGS)
 
 accounts_dialog_SOURCES = \
@@ -47,6 +48,7 @@ accounts_dialog_LDADD = 		\
 	$(GTK_LIBS)			\
 	$(GNOME_DESKTOP_LIBS)		\
 	$(UNIQUE_LIBS)			\
+	$(POLKIT_LIBS)			\
 	-lcrypt
 
 EXTRA_DIST = \
diff --git a/src/main.c b/src/main.c
index c10960a..7cd177b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,6 +30,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <unique/unique.h>
+#include <polkit/polkit.h>
 
 #include "um-user.h"
 #include "um-user-manager.h"
@@ -59,6 +60,8 @@ typedef struct {
         UmLanguageDialog *language_dialog;
         UmLocationDialog *location_dialog;
         UmEmailDialog *email_dialog;
+
+        PolkitAuthority *authority;
 } UserAccountDialog;
 
 static GtkWidget *
@@ -359,6 +362,8 @@ show_user (UmUser *user, UserAccountDialog *d)
         pixbuf = um_user_render_icon (user, FALSE, 48);
         image = get_widget (d, "user-icon-image");
         gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
+        image = get_widget (d, "user-icon-image2");
+        gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
         g_object_unref (pixbuf);
 
         label = get_widget (d, "full-name-value-label");
@@ -423,6 +428,234 @@ show_user (UmUser *user, UserAccountDialog *d)
 }
 
 static void
+update_data_change_buttons (GObject           *source,
+                            GAsyncResult      *res,
+                            UserAccountDialog *d)
+{
+        GError *error;
+        PolkitAuthorizationResult *result;
+        gboolean is_authorized;
+
+        error = NULL;
+        result = polkit_authority_check_authorization_finish (d->authority,
+                                                              res,
+                                                              &error);
+        if (error) {
+                g_warning ("polkit check failed: %s", error->message);
+                g_error_free (error);
+        }
+        else {
+                if (polkit_authorization_result_get_is_authorized (result) ||
+                    polkit_authorization_result_get_is_challenge (result)) {
+                        is_authorized = TRUE;
+                }
+                else {
+                        is_authorized = FALSE;
+                }
+
+                g_object_unref (result);
+        }
+
+        if (is_authorized) {
+                gtk_widget_show (get_widget (d, "user-icon-button"));
+                gtk_widget_hide (get_widget (d, "user-icon-nonbutton"));
+
+                gtk_widget_show (get_widget (d, "change-name-button"));
+                gtk_widget_show (get_widget (d, "change-password-button"));
+                gtk_widget_show (get_widget (d, "change-email-button"));
+                gtk_widget_show (get_widget (d, "change-language-button"));
+                gtk_widget_show (get_widget (d, "change-location-button"));
+        }
+        else {
+                gtk_widget_hide (get_widget (d, "user-icon-button"));
+                gtk_widget_show (get_widget (d, "user-icon-nonbutton"));
+
+                gtk_widget_hide (get_widget (d, "change-name-button"));
+                gtk_widget_hide (get_widget (d, "change-password-button"));
+                gtk_widget_hide (get_widget (d, "change-email-button"));
+                gtk_widget_hide (get_widget (d, "change-language-button"));
+                gtk_widget_hide (get_widget (d, "change-location-button"));
+        }
+}
+
+static void
+update_account_type_change_buttons (GObject           *source,
+                                    GAsyncResult      *res,
+                                    UserAccountDialog *d)
+{
+        GError *error;
+        PolkitAuthorizationResult *result;
+        gboolean is_authorized;
+
+        error = NULL;
+        result = polkit_authority_check_authorization_finish (d->authority,
+                                                              res,
+                                                              &error);
+        if (error) {
+                g_warning ("polkit check failed: %s", error->message);
+                g_error_free (error);
+        }
+        else {
+                if (polkit_authorization_result_get_is_authorized (result) ||
+                    polkit_authorization_result_get_is_challenge (result)) {
+                        is_authorized = TRUE;
+                }
+                else {
+                        is_authorized = FALSE;
+                }
+
+                g_object_unref (result);
+        }
+
+        if (is_authorized) {
+                gtk_widget_show (get_widget (d, "change-account-type-button"));
+        }
+        else {
+                gtk_widget_hide (get_widget (d, "change-account-type-button"));
+        }
+}
+
+static void
+update_change_buttons (UserAccountDialog *d, UmUser *u)
+{
+        const char *action;
+        PolkitSubject *subject;
+
+        if (um_user_get_uid (u) == geteuid ()) {
+                action = "org.freedesktop.accounts.change-own-user-data";
+        }
+        else {
+                action = "org.freedesktop.accounts.change-user-data";
+        }
+
+        subject = polkit_unix_process_new (getpid ());
+
+        polkit_authority_check_authorization (d->authority,
+                                              subject,
+                                              action,
+                                              NULL,
+                                              0,
+                                              NULL,
+                                              (GAsyncReadyCallback)update_data_change_buttons,
+                                              d);
+        polkit_authority_check_authorization (d->authority,
+                                              subject,
+                                              "org.freedesktop.accounts.change-account-type",
+                                              NULL,
+                                              0,
+                                              NULL,
+                                              (GAsyncReadyCallback)update_account_type_change_buttons,
+                                              d);
+        g_object_unref (subject);
+}
+
+static void
+update_add_button (GObject           *source,
+                   GAsyncResult      *res,
+                   UserAccountDialog *d)
+{
+        GError *error;
+        PolkitAuthorizationResult *result;
+        gboolean is_authorized;
+
+        error = NULL;
+        result = polkit_authority_check_authorization_finish (d->authority,
+                                                              res,
+                                                              &error);
+        if (error) {
+                g_warning ("polkit check failed: %s", error->message);
+                g_error_free (error);
+        }
+        else {
+                if (polkit_authorization_result_get_is_authorized (result) ||
+                    polkit_authorization_result_get_is_challenge (result)) {
+                        is_authorized = TRUE;
+                }
+                else {
+                        is_authorized = FALSE;
+                }
+
+                g_object_unref (result);
+        }
+
+        if (!is_authorized) {
+                gtk_widget_set_sensitive (get_widget (d, "add-user-button"), FALSE);
+        }
+
+        if (!gtk_widget_is_sensitive (get_widget (d, "add-user-button")) &&
+            !gtk_widget_is_sensitive (get_widget (d, "delete-user-button"))) {
+                gtk_widget_hide (get_widget (d, "add-delete-buttonbox"));
+        }
+}
+
+static void
+update_delete_button (GObject           *source,
+                      GAsyncResult      *res,
+                      UserAccountDialog *d)
+{
+        GError *error;
+        PolkitAuthorizationResult *result;
+        gboolean is_authorized;
+
+        error = NULL;
+        result = polkit_authority_check_authorization_finish (d->authority,
+                                                              res,
+                                                              &error);
+        if (error) {
+                g_warning ("polkit check failed: %s", error->message);
+                g_error_free (error);
+        }
+        else {
+                if (polkit_authorization_result_get_is_authorized (result) ||
+                    polkit_authorization_result_get_is_challenge (result)) {
+                        is_authorized = TRUE;
+                }
+                else {
+                        is_authorized = FALSE;
+                }
+
+                g_object_unref (result);
+        }
+
+        if (!is_authorized) {
+                gtk_widget_set_sensitive (get_widget (d, "delete-user-button"), FALSE);
+        }
+
+        if (!gtk_widget_is_sensitive (get_widget (d, "add-user-button")) &&
+            !gtk_widget_is_sensitive (get_widget (d, "delete-user-button"))) {
+                gtk_widget_hide (get_widget (d, "add-delete-buttonbox"));
+        }
+}
+
+static void
+update_create_buttons (UserAccountDialog *d)
+{
+        const char *action;
+        PolkitSubject *subject;
+
+        subject = polkit_unix_process_new (getpid ());
+
+        polkit_authority_check_authorization (d->authority,
+                                              subject,
+                                              "org.freedesktop.accounts.create-user",
+                                              NULL,
+                                              0,
+                                              NULL,
+                                              (GAsyncReadyCallback)update_add_button,
+                                              d);
+        polkit_authority_check_authorization (d->authority,
+                                              subject,
+                                              "org.freedesktop.accounts.delete-user",
+                                              NULL,
+                                              0,
+                                              NULL,
+                                              (GAsyncReadyCallback)update_delete_button,
+                                              d);
+
+        g_object_unref (subject);
+}
+
+static void
 selected_user_changed (GtkTreeSelection *selection, UserAccountDialog *d)
 {
         GtkWidget *widget;
@@ -433,10 +666,12 @@ selected_user_changed (GtkTreeSelection *selection, UserAccountDialog *d)
         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
                 gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
                 show_user (user, d);
-                g_object_unref (user);
 
                 widget = get_widget (d, "login-options-button");
                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+                update_change_buttons (d, user);
+
+                g_object_unref (user);
         }
 }
 
@@ -648,6 +883,8 @@ setup_main_window (UserAccountDialog *d)
         button = get_widget (d, "login-options-button");
         g_signal_connect (button, "clicked", G_CALLBACK (toggle_login_options), d);
 
+        update_create_buttons (d);
+
         button = get_widget (d, "user-icon-button");
         g_signal_connect (button, "clicked", G_CALLBACK (change_icon), d);
 
@@ -829,6 +1066,8 @@ main (int argc, char *argv[])
                 exit (1);
         }
 
+        d->authority = polkit_authority_get ();
+
         setup_login_options (d);
         setup_main_window (d);
         d->account_type_dialog = um_account_type_dialog_new ();



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