PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Tue Jan 27 12:11:48 PST 2009


 data/org.freedesktop.PolicyKit1.Authority.xml   |    4 +
 docs/TODO                                       |    7 --
 src/polkit/polkitauthority.c                    |   38 ++++++++++++
 src/polkitbackend/polkitbackendactionpool.c     |   76 +++++++++++++++++++++++-
 src/polkitbackend/polkitbackendauthority.c      |   23 +++++++
 src/polkitbackend/polkitbackendauthority.h      |    5 +
 src/polkitbackend/polkitbackendlocalauthority.c |   21 ++++++
 src/polkitbackend/polkitbackendserver.c         |   16 +++++
 8 files changed, 181 insertions(+), 9 deletions(-)

New commits:
commit 2b25c7e385c5cea29bc59422dc409e65f1bbca0b
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Jan 27 15:09:32 2009 -0500

    add Changed() signal that is fired when actions/authorizations change

diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
index 4a15f74..e362d7a 100644
--- a/data/org.freedesktop.PolicyKit1.Authority.xml
+++ b/data/org.freedesktop.PolicyKit1.Authority.xml
@@ -249,5 +249,9 @@
       </arg>
     </method>
 
+    <signal name="Changed">
+      <annotation name="org.gtk.EggDBus.DocString" value="Emitted when actions and/or authorizations change"/>
+    </signal>
+
   </interface>
 </node>
diff --git a/docs/TODO b/docs/TODO
index 5757d48..cd5329a 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -46,13 +46,10 @@ Core TODO items
    sudo-style authentication (e.g. select one or more identities that the
    user can choose to authenticate as)
 
- - emit a Changed() signal on the Authority interface when authorizations
-   change
-
  - provide a way to cancel a CheckAuthorization() call
 
- - use file monitors on the /usr/share/polkit-1/actions and
-   /var/lib/polkit-1 directories and DTRT
+ - maybe use file monitors on /var/lib/polkit-1 directories and
+   emit the Changed() signal
 
 Backend TODO items
 ------------------
diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c
index 70324fe..c8e6c8e 100644
--- a/src/polkit/polkitauthority.c
+++ b/src/polkit/polkitauthority.c
@@ -57,9 +57,26 @@ struct _PolkitAuthorityClass
 
 static PolkitAuthority *the_authority = NULL;
 
+enum
+{
+  CHANGED_SIGNAL,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
 G_DEFINE_TYPE (PolkitAuthority, polkit_authority, G_TYPE_OBJECT);
 
 static void
+real_authority_changed (_PolkitAuthority *real_authority,
+                        gpointer user_data)
+{
+  PolkitAuthority *authority = POLKIT_AUTHORITY (user_data);
+
+  g_signal_emit_by_name (authority, "changed");
+}
+
+static void
 polkit_authority_init (PolkitAuthority *authority)
 {
   authority->system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
@@ -69,6 +86,11 @@ polkit_authority_init (PolkitAuthority *authority)
                                                                             "/org/freedesktop/PolicyKit1/Authority");
 
   authority->real = _POLKIT_QUERY_INTERFACE_AUTHORITY (authority->authority_object_proxy);
+
+  g_signal_connect (authority->real,
+                    "changed",
+                    (GCallback) real_authority_changed,
+                    authority);
 }
 
 static void
@@ -93,6 +115,22 @@ polkit_authority_class_init (PolkitAuthorityClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   gobject_class->finalize = polkit_authority_finalize;
+
+  /**
+   * PolkitAuthority::changed:
+   * @authority: A #PolkitAuthority.
+   *
+   * Emitted when actions and/or authorizations change
+   */
+  signals[CHANGED_SIGNAL] = g_signal_new ("changed",
+                                          POLKIT_TYPE_AUTHORITY,
+                                          G_SIGNAL_RUN_LAST,
+                                          0,                      /* class offset     */
+                                          NULL,                   /* accumulator      */
+                                          NULL,                   /* accumulator data */
+                                          g_cclosure_marshal_VOID__VOID,
+                                          G_TYPE_NONE,
+                                          0);
 }
 
 PolkitAuthority *
diff --git a/src/polkitbackend/polkitbackendactionpool.c b/src/polkitbackend/polkitbackendactionpool.c
index 7604906..b63e046 100644
--- a/src/polkitbackend/polkitbackendactionpool.c
+++ b/src/polkitbackend/polkitbackendactionpool.c
@@ -19,8 +19,6 @@
  * Author: David Zeuthen <davidz at redhat.com>
  */
 
-/* TODO: watch for directory / file changes */
-
 #include "config.h"
 #include <errno.h>
 #include <pwd.h>
@@ -88,6 +86,8 @@ typedef struct
   /* directory with .policy files, e.g. /usr/share/polkit-1/actions */
   GFile *directory;
 
+  GFileMonitor *dir_monitor;
+
   /* maps from action_id to a ParsedAction struct */
   GHashTable *parsed_actions;
 
@@ -107,6 +107,14 @@ enum
 
 #define POLKIT_BACKEND_ACTION_POOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_BACKEND_TYPE_ACTION_POOL, PolkitBackendActionPoolPrivate))
 
+enum
+{
+  CHANGED_SIGNAL,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
 G_DEFINE_TYPE (PolkitBackendActionPool, polkit_backend_action_pool, G_TYPE_OBJECT);
 
 static void
@@ -139,6 +147,9 @@ polkit_backend_action_pool_finalize (GObject *object)
   if (priv->directory != NULL)
     g_object_unref (priv->directory);
 
+  if (priv->dir_monitor != NULL)
+    g_object_unref (priv->dir_monitor);
+
   if (priv->parsed_actions != NULL)
     g_hash_table_unref (priv->parsed_actions);
 
@@ -173,6 +184,32 @@ polkit_backend_action_pool_get_property (GObject     *object,
 }
 
 static void
+dir_monitor_changed (GFileMonitor     *monitor,
+                     GFile            *file,
+                     GFile            *other_file,
+                     GFileMonitorEvent event_type,
+                     gpointer          user_data)
+{
+  PolkitBackendActionPool *pool;
+  PolkitBackendActionPoolPrivate *priv;
+
+  pool = POLKIT_BACKEND_ACTION_POOL (user_data);
+  priv = POLKIT_BACKEND_ACTION_POOL_GET_PRIVATE (pool);
+
+  /* TODO: maybe rate-limit so storms of events are collapsed into one with a 500ms resolution?
+   *       Because when editing a file with emacs we get 4-8 events..
+   */
+
+  /* now throw away all caches */
+  g_hash_table_remove_all (priv->parsed_files);
+  g_hash_table_remove_all (priv->parsed_actions);
+  priv->has_loaded_all_files = FALSE;
+
+  g_signal_emit_by_name (pool, "changed");
+}
+
+
+static void
 polkit_backend_action_pool_set_property (GObject       *object,
                                          guint          prop_id,
                                          const GValue  *value,
@@ -180,6 +217,7 @@ polkit_backend_action_pool_set_property (GObject       *object,
 {
   PolkitBackendActionPool *pool;
   PolkitBackendActionPoolPrivate *priv;
+  GError *error;
 
   pool = POLKIT_BACKEND_ACTION_POOL (object);
   priv = POLKIT_BACKEND_ACTION_POOL_GET_PRIVATE (pool);
@@ -188,6 +226,24 @@ polkit_backend_action_pool_set_property (GObject       *object,
     {
     case PROP_DIRECTORY:
       priv->directory = g_value_dup_object (value);
+
+      error = NULL;
+      priv->dir_monitor = g_file_monitor_directory (priv->directory,
+                                                    G_FILE_MONITOR_NONE,
+                                                    NULL,
+                                                    &error);
+      if (priv->dir_monitor == NULL)
+        {
+          g_warning ("Error monitoring actions directory: %s", error->message);
+          g_error_free (error);
+        }
+      else
+        {
+          g_signal_connect (priv->dir_monitor,
+                            "changed",
+                            (GCallback) dir_monitor_changed,
+                            pool);
+        }
       break;
 
     default:
@@ -223,6 +279,22 @@ polkit_backend_action_pool_class_init (PolkitBackendActionPoolClass *klass)
                                                         G_PARAM_STATIC_NAME |
                                                         G_PARAM_STATIC_NICK |
                                                         G_PARAM_STATIC_BLURB));
+
+  /**
+   * PolkitBackendActionPool::changed:
+   * @action_pool: A #PolkitBackendActionPool.
+   *
+   * Emitted when action files in the supplied directory changes.
+   */
+  signals[CHANGED_SIGNAL] = g_signal_new ("changed",
+                                          POLKIT_BACKEND_TYPE_ACTION_POOL,
+                                          G_SIGNAL_RUN_LAST,
+                                          0,                      /* class offset     */
+                                          NULL,                   /* accumulator      */
+                                          NULL,                   /* accumulator data */
+                                          g_cclosure_marshal_VOID__VOID,
+                                          G_TYPE_NONE,
+                                          0);
 }
 
 /**
diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
index 5f06e10..0599381 100644
--- a/src/polkitbackend/polkitbackendauthority.c
+++ b/src/polkitbackend/polkitbackendauthority.c
@@ -26,6 +26,14 @@
 #include <polkit/polkit.h>
 #include "polkitbackendauthority.h"
 
+enum
+{
+  CHANGED_SIGNAL,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
 G_DEFINE_ABSTRACT_TYPE (PolkitBackendAuthority, polkit_backend_authority, G_TYPE_OBJECT);
 
 static void
@@ -36,6 +44,21 @@ polkit_backend_authority_init (PolkitBackendAuthority *local_authority)
 static void
 polkit_backend_authority_class_init (PolkitBackendAuthorityClass *klass)
 {
+  /**
+   * PolkitBackendAuthority::changed:
+   * @authority: A #PolkitBackendAuthority.
+   *
+   * Emitted when actions and/or authorizations change
+   */
+  signals[CHANGED_SIGNAL] = g_signal_new ("changed",
+                                          POLKIT_BACKEND_TYPE_AUTHORITY,
+                                          G_SIGNAL_RUN_LAST,
+                                          0,                      /* class offset     */
+                                          NULL,                   /* accumulator      */
+                                          NULL,                   /* accumulator data */
+                                          g_cclosure_marshal_VOID__VOID,
+                                          G_TYPE_NONE,
+                                          0);
 }
 
 void
diff --git a/src/polkitbackend/polkitbackendauthority.h b/src/polkitbackend/polkitbackendauthority.h
index 06f54fa..70841e5 100644
--- a/src/polkitbackend/polkitbackendauthority.h
+++ b/src/polkitbackend/polkitbackendauthority.h
@@ -51,6 +51,11 @@ struct _PolkitBackendAuthorityClass
 
   /*< public >*/
 
+  /* Signals */
+  void (*changed)  (PolkitBackendAuthority   *authority);
+
+  /* VTable */
+
   /* TODO: need something more efficient such that we don't watch all name changes */
   void (*system_bus_name_owner_changed)  (PolkitBackendAuthority   *authority,
                                           const gchar              *name,
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index ec47a05..fea424a 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -184,22 +184,36 @@ static void polkit_backend_local_authority_authentication_agent_response (Polkit
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static void
+action_pool_changed (PolkitBackendActionPool *action_pool,
+                     PolkitBackendLocalAuthority *authority)
+{
+  g_signal_emit_by_name (authority, "changed");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 G_DEFINE_TYPE (PolkitBackendLocalAuthority, polkit_backend_local_authority, POLKIT_BACKEND_TYPE_AUTHORITY);
 
 #define POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_BACKEND_TYPE_LOCAL_AUTHORITY, PolkitBackendLocalAuthorityPrivate))
 
 static void
-polkit_backend_local_authority_init (PolkitBackendLocalAuthority *local_authority)
+polkit_backend_local_authority_init (PolkitBackendLocalAuthority *authority)
 {
   PolkitBackendLocalAuthorityPrivate *priv;
   GFile *action_desc_directory;
 
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
+  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
 
   action_desc_directory = g_file_new_for_path (PACKAGE_DATA_DIR "/polkit-1/actions");
   priv->action_pool = polkit_backend_action_pool_new (action_desc_directory);
   g_object_unref (action_desc_directory);
 
+  g_signal_connect (priv->action_pool,
+                    "changed",
+                    (GCallback) action_pool_changed,
+                    authority);
+
   priv->hash_identity_to_authority_store = g_hash_table_new_full ((GHashFunc) polkit_identity_hash,
                                                                   (GEqualFunc) polkit_identity_equal,
                                                                   (GDestroyNotify) g_object_unref,
@@ -2219,6 +2233,9 @@ add_authorization_for_identity (PolkitBackendLocalAuthority *authority,
                                                authorization,
                                                error);
 
+  if (ret)
+    g_signal_emit_by_name (authority, "changed");
+
  out:
   return ret;
 }
diff --git a/src/polkitbackend/polkitbackendserver.c b/src/polkitbackend/polkitbackendserver.c
index ae1940a..25fb96c 100644
--- a/src/polkitbackend/polkitbackendserver.c
+++ b/src/polkitbackend/polkitbackendserver.c
@@ -51,6 +51,8 @@ struct _PolkitBackendServer
   EggDBusBus *bus;
 
   gulong name_owner_changed_id;
+
+  gulong authority_changed_id;
 };
 
 struct _PolkitBackendServerClass
@@ -82,6 +84,8 @@ polkit_backend_server_finalize (GObject *object)
 
   g_object_unref (server->system_bus);
 
+  g_signal_handler_disconnect (server->authority, server->authority_changed_id);
+
   g_object_unref (server->authority);
 }
 
@@ -105,6 +109,13 @@ name_owner_changed (EggDBusBus *instance,
   polkit_backend_authority_system_bus_name_owner_changed (server->authority, name, old_owner, new_owner);
 }
 
+static void
+authority_changed (PolkitBackendAuthority *authority,
+                   PolkitBackendServer *server)
+{
+  _polkit_authority_emit_signal_changed (_POLKIT_AUTHORITY (server), NULL);
+}
+
 PolkitBackendServer *
 polkit_backend_server_new (PolkitBackendAuthority *authority)
 {
@@ -128,6 +139,11 @@ polkit_backend_server_new (PolkitBackendAuthority *authority)
                                                     (GCallback) name_owner_changed,
                                                     server);
 
+  server->authority_changed_id = g_signal_connect (authority,
+                                                   "changed",
+                                                   (GCallback) authority_changed,
+                                                   server);
+
   return server;
 }
 


More information about the hal-commit mailing list