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