Complete most of implementation, thread safety

Not tested or run yet
This commit is contained in:
Stef Walter 2012-01-20 15:10:35 +01:00
parent 805355e78e
commit 31d8f1508e
16 changed files with 3066 additions and 926 deletions

View File

@ -15,12 +15,13 @@ BUILT_SOURCES = \
gsecret-dbus-generated.c gsecret-dbus-generated.h gsecret-dbus-generated.c gsecret-dbus-generated.h
libgsecret_la_SOURCES = \ libgsecret_la_SOURCES = \
gsecret-value.h gsecret-value.c \ gsecret-collection.h gsecret-collection.c \
gsecret-item.h gsecret-item.c \ gsecret-item.h gsecret-item.c \
gsecret-password.h gsecret-password.c \ gsecret-password.h gsecret-password.c \
gsecret-prompt.h gsecret-prompt.c \ gsecret-prompt.h gsecret-prompt.c \
gsecret-service.h gsecret-service.c \ gsecret-service.h gsecret-service.c \
gsecret-util.c \ gsecret-util.c \
gsecret-value.h gsecret-value.c \
$(BUILT_SOURCES) \ $(BUILT_SOURCES) \
$(NULL) $(NULL)

View File

@ -0,0 +1,677 @@
/* GSecret - GLib wrapper for Secret Service
*
* Copyright 2011 Red Hat Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* See the included COPYING file for more information.
*/
#include "config.h"
#include "gsecret-collection.h"
#include "gsecret-dbus-generated.h"
#include "gsecret-item.h"
#include "gsecret-private.h"
#include "gsecret-service.h"
#include "gsecret-types.h"
#include <glib/gi18n-lib.h>
enum {
PROP_0,
PROP_ITEMS,
PROP_LABEL,
PROP_LOCKED,
PROP_CREATED,
PROP_MODIFIED
};
struct _GSecretCollectionPrivate {
/* Doesn't change between construct and finalize */
GSecretService *service;
GCancellable *cancellable;
/* Protected by mutex */
GMutex mutex;
GHashTable *items;
};
G_DEFINE_TYPE (GSecretCollection, gsecret_collection, G_TYPE_DBUS_PROXY);
static GHashTable *
items_table_new (void)
{
return g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
}
static void
gsecret_collection_init (GSecretCollection *self)
{
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GSECRET_TYPE_COLLECTION,
GSecretCollectionPrivate);
g_mutex_init (&self->pv->mutex);
self->pv->cancellable = g_cancellable_new ();
self->pv->items = items_table_new ();
}
static void
on_set_label (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSecretCollection *self = GSECRET_COLLECTION (user_data);
GError *error = NULL;
gsecret_collection_set_label_finish (self, result, &error);
if (error != NULL) {
g_warning ("couldn't set GSecretCollection Label: %s", error->message);
g_error_free (error);
}
g_object_unref (self);
}
static void
gsecret_collection_set_property (GObject *obj,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GSecretCollection *self = GSECRET_COLLECTION (obj);
switch (prop_id) {
case PROP_LABEL:
gsecret_collection_set_label (self, g_value_get_string (value),
self->pv->cancellable, on_set_label,
g_object_ref (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
}
}
static void
gsecret_collection_get_property (GObject *obj,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GSecretCollection *self = GSECRET_COLLECTION (obj);
switch (prop_id) {
case PROP_ITEMS:
g_value_take_boxed (value, gsecret_collection_get_items (self));
break;
case PROP_LABEL:
g_value_take_string (value, gsecret_collection_get_label (self));
break;
case PROP_LOCKED:
g_value_set_boolean (value, gsecret_collection_get_locked (self));
break;
case PROP_CREATED:
g_value_set_uint64 (value, gsecret_collection_get_created (self));
break;
case PROP_MODIFIED:
g_value_set_uint64 (value, gsecret_collection_get_modified (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
}
}
static void
gsecret_collection_dispose (GObject *obj)
{
GSecretCollection *self = GSECRET_COLLECTION (obj);
g_clear_object (&self->pv->service);
g_cancellable_cancel (self->pv->cancellable);
G_OBJECT_GET_CLASS (obj)->dispose (obj);
}
static void
gsecret_collection_finalize (GObject *obj)
{
GSecretCollection *self = GSECRET_COLLECTION (obj);
g_mutex_clear (&self->pv->mutex);
g_hash_table_destroy (self->pv->items);
g_object_unref (self->pv->cancellable);
G_OBJECT_GET_CLASS (obj)->finalize (obj);
}
typedef struct {
GCancellable *cancellable;
GHashTable *items;
gint items_loading;
} LoadClosure;
static void
load_closure_free (gpointer data)
{
LoadClosure *closure = data;
g_clear_object (&closure->cancellable);
g_hash_table_unref (closure->items);
g_slice_free (LoadClosure, closure);
}
static GSimpleAsyncResult *
load_result_new (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
LoadClosure *closure;
res = g_simple_async_result_new (NULL, callback, user_data, load_result_new);
closure = g_slice_new (LoadClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->items = items_table_new ();
g_simple_async_result_set_op_res_gpointer (res, closure, load_closure_free);
return res;
}
static void
load_items_complete (GSecretCollection *self,
GSimpleAsyncResult *res)
{
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GHashTable *items;
g_assert (closure->items_loading == 0);
g_hash_table_ref (closure->items);
g_mutex_lock (&self->pv->mutex);
items = self->pv->items;
self->pv->items = closure->items;
g_mutex_unlock (&self->pv->mutex);
g_hash_table_unref (items);
g_simple_async_result_complete (res);
}
static void
on_item_loading (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretCollection *self = GSECRET_COLLECTION (g_async_result_get_source_object (user_data));
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
const gchar *item_path;
GError *error = NULL;
GSecretItem *item;
closure->items_loading--;
item = gsecret_item_new_finish (result, &error);
if (error != NULL)
g_simple_async_result_take_error (res, error);
if (item != NULL) {
item_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
g_hash_table_insert (closure->items, g_strdup (item_path), item);
}
if (closure->items_loading == 0)
load_items_complete (self, res);
g_object_unref (self);
g_object_unref (res);
}
static void
load_items_perform (GSecretCollection *self,
GSimpleAsyncResult *res,
GVariant *item_paths)
{
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GSecretItem *item;
GVariantIter iter;
gchar *item_path;
g_variant_iter_init (&iter, item_paths);
while (g_variant_iter_loop (&iter, "o", &item_path)) {
g_mutex_lock (&self->pv->mutex);
item = g_hash_table_lookup (self->pv->items, item_path);
if (item == NULL)
g_object_ref (item);
g_mutex_unlock (&self->pv->mutex);
if (item == NULL) {
gsecret_item_new (self->pv->service, item_path,
closure->cancellable, on_item_loading,
g_object_ref (res));
closure->items_loading++;
} else {
g_hash_table_insert (closure->items,
g_strdup (item_path), item);
}
}
if (closure->items_loading == 0)
load_items_complete (self, res);
g_variant_unref (item_paths);
}
static void
handle_property_changed (GSecretCollection *self,
const gchar *property_name,
GVariant *value)
{
GSimpleAsyncResult *res;
if (g_str_equal (property_name, "Label"))
g_object_notify (G_OBJECT (self), "label");
else if (g_str_equal (property_name, "Locked"))
g_object_notify (G_OBJECT (self), "locked");
else if (g_str_equal (property_name, "Created"))
g_object_notify (G_OBJECT (self), "created");
else if (g_str_equal (property_name, "Modified"))
g_object_notify (G_OBJECT (self), "modified");
else if (g_str_equal (property_name, "Items")) {
res = load_result_new (self->pv->cancellable, NULL, NULL);
if (value == NULL)
value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Items");
else
g_variant_ref (value);
if (value == NULL) {
g_warning ("couldn't retrieve Collection Items property");
g_simple_async_result_complete (res);
} else {
load_items_perform (self, res, value);
g_variant_unref (value);
}
g_object_unref (res);
}
}
static void
gsecret_collection_properties_changed (GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties)
{
GSecretCollection *self = GSECRET_COLLECTION (proxy);
gchar *property_name;
GVariantIter iter;
GVariant *value;
g_object_freeze_notify (G_OBJECT (self));
g_variant_iter_init (&iter, changed_properties);
while (g_variant_iter_loop (&iter, "{sv}", &property_name, &value))
handle_property_changed (self, property_name, value);
g_object_thaw_notify (G_OBJECT (self));
}
static void
gsecret_collection_class_init (GSecretCollectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GDBusProxyClass *proxy_class = G_DBUS_PROXY_CLASS (klass);
gobject_class->get_property = gsecret_collection_get_property;
gobject_class->set_property = gsecret_collection_set_property;
gobject_class->dispose = gsecret_collection_dispose;
gobject_class->finalize = gsecret_collection_finalize;
proxy_class->g_properties_changed = gsecret_collection_properties_changed;
g_object_class_install_property (gobject_class, PROP_ITEMS,
g_param_spec_boxed ("items", "Items", "Items in collection",
_gsecret_list_get_type (), G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_LABEL,
g_param_spec_string ("label", "Label", "Item label",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_LOCKED,
g_param_spec_boolean ("locked", "Locked", "Item locked",
TRUE, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_CREATED,
g_param_spec_uint64 ("created", "Created", "Item creation date",
0UL, G_MAXUINT64, 0UL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_MODIFIED,
g_param_spec_uint64 ("modified", "Modified", "Item modified date",
0UL, G_MAXUINT64, 0UL, G_PARAM_READWRITE));
}
static void
on_collection_new (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GObject *source_object;
GError *error = NULL;
GObject *object;
source_object = g_async_result_get_source_object (user_data);
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
result, &error);
g_object_unref (source_object);
if (error == NULL) {
load_items_perform (GSECRET_COLLECTION (object), res, NULL);
g_simple_async_result_set_op_res_gpointer (res, object, g_object_unref);
} else {
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
}
g_object_unref (res);
}
void
gsecret_collection_new (GSecretService *service,
const gchar *collection_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
GDBusProxy *proxy;
g_return_if_fail (GSECRET_IS_SERVICE (service));
g_return_if_fail (collection_path != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = load_result_new (cancellable, callback, user_data);
proxy = G_DBUS_PROXY (service);
g_async_initable_new_async (GSECRET_SERVICE_GET_CLASS (service)->collection_gtype,
G_PRIORITY_DEFAULT,
cancellable,
on_collection_new,
g_object_ref (res),
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_collection_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
"g-connection", g_dbus_proxy_get_connection (proxy),
"g-object-path", collection_path,
"g-interface-name", GSECRET_COLLECTION_INTERFACE,
NULL);
g_object_unref (res);
}
GSecretCollection *
gsecret_collection_new_finish (GAsyncResult *result,
GError **error)
{
GObject *object;
GObject *source_object;
source_object = g_async_result_get_source_object (result);
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
result, error);
g_object_unref (source_object);
if (object != NULL)
return GSECRET_COLLECTION (object);
else
return NULL;
}
GSecretCollection *
gsecret_collection_new_sync (GSecretService *service,
const gchar *collection_path,
GCancellable *cancellable,
GError **error)
{
GSecretSync *sync;
GSecretCollection *collection;
g_return_val_if_fail (GSECRET_IS_SERVICE (service), NULL);
g_return_val_if_fail (collection_path != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
sync = _gsecret_sync_new ();
g_main_context_push_thread_default (sync->context);
gsecret_collection_new (service, collection_path, cancellable,
_gsecret_sync_on_result, sync);
g_main_loop_run (sync->loop);
collection = gsecret_collection_new_finish (sync->result, error);
g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
return collection;
}
void
gsecret_collection_refresh (GSecretCollection *self)
{
g_return_if_fail (GSECRET_IS_COLLECTION (self));
_gsecret_util_get_properties (G_DBUS_PROXY (self),
gsecret_collection_refresh,
self->pv->cancellable, NULL, NULL);
}
void
gsecret_collection_delete (GSecretCollection *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
const gchar *object_path;
g_return_if_fail (GSECRET_IS_COLLECTION (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
gsecret_service_delete_path (self->pv->service, object_path, cancellable,
callback, user_data);
}
gboolean
gsecret_collection_delete_finish (GSecretCollection *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return gsecret_service_delete_path_finish (self->pv->service, result, error);
}
gboolean
gsecret_collection_delete_sync (GSecretCollection *self,
GCancellable *cancellable,
GError **error)
{
GSecretSync *sync;
gboolean ret;
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
sync = _gsecret_sync_new ();
g_main_context_push_thread_default (sync->context);
gsecret_collection_delete (self, cancellable, _gsecret_sync_on_result, sync);
g_main_loop_run (sync->loop);
ret = gsecret_collection_delete_finish (self, sync->result, error);
g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
return ret;
}
GList *
gsecret_collection_get_items (GSecretCollection *self)
{
GList *l, *items;
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), NULL);
g_mutex_lock (&self->pv->mutex);
items = g_hash_table_get_values (self->pv->items);
for (l = items; l != NULL; l = g_list_next (l))
g_object_ref (l->data);
g_mutex_unlock (&self->pv->mutex);
return items;
}
GSecretItem *
_gsecret_collection_find_item_instance (GSecretCollection *self,
const gchar *item_path)
{
GSecretItem *item;
g_mutex_lock (&self->pv->mutex);
item = g_hash_table_lookup (self->pv->items, item_path);
if (item != NULL)
g_object_ref (item);
g_mutex_unlock (&self->pv->mutex);
return item;
}
gchar *
gsecret_collection_get_label (GSecretCollection *self)
{
GVariant *variant;
gchar *label;
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), NULL);
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Label");
g_return_val_if_fail (variant != NULL, NULL);
label = g_variant_dup_string (variant, NULL);
g_variant_unref (variant);
return label;
}
void
gsecret_collection_set_label (GSecretCollection *self,
const gchar *label,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (GSECRET_IS_ITEM (self));
g_return_if_fail (label != NULL);
_gsecret_util_set_property (G_DBUS_PROXY (self), "Label",
g_variant_new_string (label),
gsecret_collection_set_label,
cancellable, callback, user_data);
}
gboolean
gsecret_collection_set_label_finish (GSecretCollection *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE);
return _gsecret_util_set_property_finish (G_DBUS_PROXY (self),
gsecret_collection_set_label,
result, error);
}
gboolean
gsecret_collection_set_label_sync (GSecretCollection *self,
const gchar *label,
GCancellable *cancellable,
GError **error)
{
g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE);
g_return_val_if_fail (label != NULL, FALSE);
return _gsecret_util_set_property_sync (G_DBUS_PROXY (self), "Label",
g_variant_new_string (label),
cancellable, error);
}
gboolean
gsecret_collection_get_locked (GSecretCollection *self)
{
GVariant *variant;
gboolean locked;
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), TRUE);
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Locked");
g_return_val_if_fail (variant != NULL, TRUE);
locked = g_variant_get_boolean (variant);
g_variant_unref (variant);
return locked;
}
guint64
gsecret_collection_get_created (GSecretCollection *self)
{
GVariant *variant;
guint64 created;
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), TRUE);
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Created");
g_return_val_if_fail (variant != NULL, 0);
created = g_variant_get_uint64 (variant);
g_variant_unref (variant);
return created;
}
guint64
gsecret_collection_get_modified (GSecretCollection *self)
{
GVariant *variant;
guint64 modified;
g_return_val_if_fail (GSECRET_IS_COLLECTION (self), TRUE);
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Modified");
g_return_val_if_fail (variant != NULL, 0);
modified = g_variant_get_uint64 (variant);
g_variant_unref (variant);
return modified;
}

View File

@ -10,57 +10,91 @@
* See the included COPYING file for more information. * See the included COPYING file for more information.
*/ */
#ifndef __GSECRET_SERVICE_H__ #ifndef __GSECRET_COLLECTION_H__
#define __GSECRET_SERVICE_H__ #define __GSECRET_COLLECTION_H__
#include <gio/gio.h> #include <gio/gio.h>
#include "gsecret-types.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GSECRET_TYPE_SERVICE (gsecret_service_get_type ()) #define GSECRET_TYPE_COLLECTION (gsecret_collection_get_type ())
#define GSECRET_SERVICE(inst) (GSECRET_TYPE_CHECK_INSTANCE_CAST ((inst), GSECRET_TYPE_SERVICE, GSecretService)) #define GSECRET_COLLECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), GSECRET_TYPE_COLLECTION, GSecretCollection))
#define GSECRET_SERVICE_CLASS(class) (GSECRET_TYPE_CHECK_CLASS_CAST ((class), GSECRET_TYPE_SERVICE, GSecretServiceClass)) #define GSECRET_COLLECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), GSECRET_TYPE_COLLECTION, GSecretCollectionClass))
#define GSECRET_IS_SERVICE(inst) (GSECRET_TYPE_CHECK_INSTANCE_TYPE ((inst), GSECRET_TYPE_SERVICE)) #define GSECRET_IS_COLLECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), GSECRET_TYPE_COLLECTION))
#define GSECRET_IS_SERVICE_CLASS(class) (GSECRET_TYPE_CHECK_CLASS_TYPE ((class), GSECRET_TYPE_SERVICE)) #define GSECRET_IS_COLLECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), GSECRET_TYPE_COLLECTION))
#define GSECRET_SERVICE_GET_CLASS(inst) (GSECRET_TYPE_INSTANCE_GET_CLASS ((inst), GSECRET_TYPE_SERVICE, GSecretServiceClass)) #define GSECRET_COLLECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), GSECRET_TYPE_COLLECTION, GSecretCollectionClass))
typedef struct _GSecretServiceClass GSecretServiceClass; typedef struct _GSecretCollectionClass GSecretCollectionClass;
typedef struct _GSecretServicePrivate GSecretServicePrivate; typedef struct _GSecretCollectionPrivate GSecretCollectionPrivate;
struct _GSecretServiceClass { struct _GSecretCollection {
GDBusProxy parent;
GSecretCollectionPrivate *pv;
};
struct _GSecretCollectionClass {
GDBusProxyClass parent_class; GDBusProxyClass parent_class;
gpointer padding[8];
GType collection_type;
GType item_type;
padding;
}; };
struct _GSecretService { GType gsecret_collection_get_type (void) G_GNUC_CONST;
GDBusProxy parent_instance;
GSecretServicePrivate *pv;
};
GType gsecret_service_get_type (void) G_GNUC_CONST; void gsecret_collection_new (GSecretService *service,
const gchar *collection_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSecretService* gsecret_collection_xxx_new (void); GSecretCollection * gsecret_collection_new_finish (GAsyncResult *result,
GError **error);
GSecretCollection* gsecret_collection_instance (GDBusConnection *connection, GSecretCollection * gsecret_collection_new_sync (GSecretService *service,
const gchar *object_path); const gchar *collection_path,
GCancellable *cancellable,
GError **error);
gsecret_collection_delete void gsecret_collection_refresh (GSecretCollection *self);
gsecret_collection_search
GSecretItem* gsecret_collection_create_item (xxxx); void gsecret_collection_delete (GSecretCollection *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean gsecret_collection_delete_finish (GSecretCollection *self,
GAsyncResult *result,
GError **error);
gsecret_collection_get_items gboolean gsecret_collection_delete_sync (GSecretCollection *self,
gsecret_collection_get_label GCancellable *cancellable,
gsecret_collection_set_label GError **error);
gsecret_collection_get_locked
gsecret_collection_get_created GList * gsecret_collection_get_items (GSecretCollection *self);
gsecret_collection_get_modified
gchar * gsecret_collection_get_label (GSecretCollection *self);
void gsecret_collection_set_label (GSecretCollection *self,
const gchar *label,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean gsecret_collection_set_label_finish (GSecretCollection *self,
GAsyncResult *result,
GError **error);
gboolean gsecret_collection_set_label_sync (GSecretCollection *self,
const gchar *label,
GCancellable *cancellable,
GError **error);
gboolean gsecret_collection_get_locked (GSecretCollection *self);
guint64 gsecret_collection_get_created (GSecretCollection *self);
guint64 gsecret_collection_get_modified (GSecretCollection *self);
G_END_DECLS G_END_DECLS
#endif /* __G_SERVICE_H___ */ #endif /* __GSECRET_COLLECTION_H___ */

View File

@ -12,6 +12,7 @@
#include "config.h" #include "config.h"
#include "gsecret-dbus-generated.h"
#include "gsecret-item.h" #include "gsecret-item.h"
#include "gsecret-private.h" #include "gsecret-private.h"
#include "gsecret-service.h" #include "gsecret-service.h"
@ -20,22 +21,329 @@
#include <glib/gi18n-lib.h> #include <glib/gi18n-lib.h>
struct _GSecretItemPrivate { enum {
GSecretService *service; PROP_0,
PROP_ATTRIBUTES,
PROP_LABEL,
PROP_LOCKED,
PROP_CREATED,
PROP_MODIFIED
}; };
/* Thread safe: no changes between construct and finalize */
typedef struct _GSecretItemPrivate {
GSecretService *service;
GCancellable *cancellable;
} GSecretItemPrivate;
G_DEFINE_TYPE (GSecretItem, gsecret_item, G_TYPE_DBUS_PROXY); G_DEFINE_TYPE (GSecretItem, gsecret_item, G_TYPE_DBUS_PROXY);
static GSecretItemPrivate *
gsecret_item_private_get (GSecretItem *self)
{
return G_TYPE_INSTANCE_GET_PRIVATE (self, GSECRET_TYPE_ITEM, GSecretItemPrivate);
}
static void static void
gsecret_item_init (GSecretItem *self) gsecret_item_init (GSecretItem *self)
{ {
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GSECRET_TYPE_ITEM, GSecretItemPrivate); GSecretItemPrivate *pv = gsecret_item_private_get (self);
pv->cancellable = g_cancellable_new ();
}
static void
on_set_attributes (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSecretItem *self = GSECRET_ITEM (user_data);
GError *error = NULL;
gsecret_item_set_attributes_finish (self, result, &error);
if (error != NULL) {
g_warning ("couldn't set GSecretItem Attributes: %s", error->message);
g_error_free (error);
}
g_object_unref (self);
}
static void
on_set_label (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSecretItem *self = GSECRET_ITEM (user_data);
GError *error = NULL;
gsecret_item_set_label_finish (self, result, &error);
if (error != NULL) {
g_warning ("couldn't set GSecretItem Label: %s", error->message);
g_error_free (error);
}
g_object_unref (self);
}
static void
gsecret_item_set_property (GObject *obj,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GSecretItem *self = GSECRET_ITEM (obj);
GSecretItemPrivate *pv = gsecret_item_private_get (self);
switch (prop_id) {
case PROP_ATTRIBUTES:
gsecret_item_set_attributes (self, g_value_get_boxed (value),
pv->cancellable, on_set_attributes,
g_object_ref (self));
break;
case PROP_LABEL:
gsecret_item_set_label (self, g_value_get_string (value),
pv->cancellable, on_set_label,
g_object_ref (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
}
}
static void
gsecret_item_get_property (GObject *obj,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GSecretItem *self = GSECRET_ITEM (obj);
switch (prop_id) {
case PROP_ATTRIBUTES:
g_value_take_boxed (value, gsecret_item_get_attributes (self));
break;
case PROP_LABEL:
g_value_take_string (value, gsecret_item_get_label (self));
break;
case PROP_LOCKED:
g_value_set_boolean (value, gsecret_item_get_locked (self));
break;
case PROP_CREATED:
g_value_set_uint64 (value, gsecret_item_get_created (self));
break;
case PROP_MODIFIED:
g_value_set_uint64 (value, gsecret_item_get_modified (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
}
}
static void
gsecret_item_dispose (GObject *obj)
{
GSecretItem *self = GSECRET_ITEM (obj);
GSecretItemPrivate *pv = gsecret_item_private_get (self);
g_clear_object (&pv->service);
g_cancellable_cancel (pv->cancellable);
G_OBJECT_GET_CLASS (obj)->dispose (obj);
}
static void
gsecret_item_finalize (GObject *obj)
{
GSecretItem *self = GSECRET_ITEM (obj);
GSecretItemPrivate *pv = gsecret_item_private_get (self);
g_clear_object (&pv->cancellable);
G_OBJECT_GET_CLASS (obj)->finalize (obj);
}
static void
handle_property_changed (GObject *object,
const gchar *property_name)
{
if (g_str_equal (property_name, "Attributes"))
g_object_notify (object, "attributes");
else if (g_str_equal (property_name, "Label"))
g_object_notify (object, "label");
else if (g_str_equal (property_name, "Locked"))
g_object_notify (object, "locked");
else if (g_str_equal (property_name, "Created"))
g_object_notify (object, "created");
else if (g_str_equal (property_name, "Modified"))
g_object_notify (object, "modified");
}
static void
gsecret_item_properties_changed (GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties)
{
GObject *obj = G_OBJECT (proxy);
gchar *property_name;
GVariantIter iter;
GVariant *value;
g_object_freeze_notify (obj);
g_variant_iter_init (&iter, changed_properties);
while (g_variant_iter_loop (&iter, "{sv}", &property_name, &value))
handle_property_changed (obj, property_name);
g_object_thaw_notify (obj);
} }
static void static void
gsecret_item_class_init (GSecretItemClass *klass) gsecret_item_class_init (GSecretItemClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GDBusProxyClass *proxy_class = G_DBUS_PROXY_CLASS (klass);
gobject_class->get_property = gsecret_item_get_property;
gobject_class->set_property = gsecret_item_set_property;
gobject_class->dispose = gsecret_item_dispose;
gobject_class->finalize = gsecret_item_finalize;
proxy_class->g_properties_changed = gsecret_item_properties_changed;
g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
g_param_spec_boxed ("attributes", "Attributes", "Item attributes",
G_TYPE_HASH_TABLE, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_LABEL,
g_param_spec_string ("label", "Label", "Item label",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_LOCKED,
g_param_spec_boolean ("locked", "Locked", "Item locked",
TRUE, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_CREATED,
g_param_spec_uint64 ("created", "Created", "Item creation date",
0UL, G_MAXUINT64, 0UL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_MODIFIED,
g_param_spec_uint64 ("modified", "Modified", "Item modified date",
0UL, G_MAXUINT64, 0UL, G_PARAM_READWRITE));
}
void
gsecret_item_new (GSecretService *service,
const gchar *item_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GDBusProxy *proxy;
g_return_if_fail (GSECRET_IS_SERVICE (service));
g_return_if_fail (item_path != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
proxy = G_DBUS_PROXY (service);
g_async_initable_new_async (GSECRET_SERVICE_GET_CLASS (service)->item_gtype,
G_PRIORITY_DEFAULT,
cancellable,
callback,
user_data,
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_item_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
"g-connection", g_dbus_proxy_get_connection (proxy),
"g-object-path", item_path,
"g-interface-name", GSECRET_ITEM_INTERFACE,
NULL);
}
GSecretItem *
gsecret_item_new_finish (GAsyncResult *result,
GError **error)
{
GObject *object;
GObject *source_object;
source_object = g_async_result_get_source_object (result);
object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
result, error);
g_object_unref (source_object);
if (object != NULL)
return GSECRET_ITEM (object);
else
return NULL;
}
GSecretItem *
gsecret_item_new_sync (GSecretService *service,
const gchar *item_path,
GCancellable *cancellable,
GError **error)
{
GInitable *initable;
GDBusProxy *proxy;
proxy = G_DBUS_PROXY (service);
g_return_val_if_fail (GSECRET_IS_SERVICE (service), NULL);
g_return_val_if_fail (item_path != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
initable = g_initable_new (GSECRET_TYPE_ITEM,
cancellable,
error,
"g-flags", G_DBUS_CALL_FLAGS_NONE,
"g-interface-info", _gsecret_gen_item_interface_info (),
"g-name", g_dbus_proxy_get_name (proxy),
"g-connection", g_dbus_proxy_get_connection (proxy),
"g-object-path", item_path,
"g-interface-name", GSECRET_ITEM_INTERFACE,
NULL);
if (initable != NULL)
return GSECRET_ITEM (initable);
else
return NULL;
}
void
gsecret_item_refresh (GSecretItem *self)
{
g_return_if_fail (GSECRET_IS_ITEM (self));
_gsecret_util_get_properties (G_DBUS_PROXY (self),
gsecret_item_refresh,
NULL, NULL, NULL);
}
static void
on_item_deleted (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretItem *self = GSECRET_ITEM (g_async_result_get_source_object (user_data));
GError *error = NULL;
if (gsecret_service_delete_path_finish (GSECRET_SERVICE (source), result, &error))
g_object_run_dispose (G_OBJECT (self));
if (error != NULL)
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
g_object_unref (self);
g_object_unref (res);
} }
void void
@ -44,14 +352,22 @@ gsecret_item_delete (GSecretItem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
GSecretItemPrivate *pv;
GSimpleAsyncResult *res;
const gchar *object_path; const gchar *object_path;
g_return_if_fail (GSECRET_IS_ITEM (self)); g_return_if_fail (GSECRET_IS_ITEM (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
pv = gsecret_item_private_get (self);
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self)); object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
gsecret_service_delete_path (self->pv->service, object_path, res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
cancellable, callback, user_data); gsecret_item_delete);
gsecret_service_delete_path (pv->service, object_path, cancellable,
on_item_deleted, g_object_ref (res));
g_object_unref (res);
} }
gboolean gboolean
@ -59,10 +375,13 @@ gsecret_item_delete_finish (GSecretItem *self,
GAsyncResult *result, GAsyncResult *result,
GError **error) GError **error)
{ {
GSecretItemPrivate *pv;
g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE); g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return gsecret_service_delete_path_finish (self->pv->service, result, error); pv = gsecret_item_private_get (self);
return gsecret_service_delete_path_finish (pv->service, result, error);
} }
gboolean gboolean
@ -70,15 +389,26 @@ gsecret_item_delete_sync (GSecretItem *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
const gchar *object_path; GSecretSync *sync;
gboolean ret;
g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE); g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self)); sync = _gsecret_sync_new ();
return gsecret_service_delete_path_sync (self->pv->service, g_main_context_push_thread_default (sync->context);
object_path, cancellable, error);
gsecret_item_delete (self, cancellable, _gsecret_sync_on_result, sync);
g_main_loop_run (sync->loop);
ret = gsecret_item_delete_finish (self, sync->result, error);
g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
return ret;
} }
static void static void
@ -86,13 +416,14 @@ on_item_get_secret_ready (GObject *source, GAsyncResult *result, gpointer user_d
{ {
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data); GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretItem *self = GSECRET_ITEM (g_async_result_get_source_object (user_data)); GSecretItem *self = GSECRET_ITEM (g_async_result_get_source_object (user_data));
GSecretItemPrivate *pv = gsecret_item_private_get (self);
GError *error = NULL; GError *error = NULL;
GSecretValue *value; GSecretValue *value;
GVariant *ret; GVariant *ret;
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
if (error == NULL) { if (error == NULL) {
value = _gsecret_service_decode_secret (self->pv->service, ret); value = _gsecret_service_decode_secret (pv->service, ret);
if (value == NULL) { if (value == NULL) {
g_set_error (&error, GSECRET_ERROR, GSECRET_ERROR_PROTOCOL, g_set_error (&error, GSECRET_ERROR, GSECRET_ERROR_PROTOCOL,
_("Received invalid secret from the secret storage")); _("Received invalid secret from the secret storage"));
@ -115,12 +446,13 @@ on_service_ensure_session (GObject *source, GAsyncResult *result, gpointer user_
{ {
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data); GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GSecretItem *self = GSECRET_ITEM (g_async_result_get_source_object (user_data)); GSecretItem *self = GSECRET_ITEM (g_async_result_get_source_object (user_data));
GSecretItemPrivate *pv = gsecret_item_private_get (self);
GError *error = NULL; GError *error = NULL;
GCancellable *cancellable = NULL; GCancellable *cancellable = NULL;
const gchar *session_path; const gchar *session_path;
session_path = _gsecret_service_ensure_session_finish (self->pv->service, session_path = _gsecret_service_ensure_session_finish (pv->service, result,
result, &cancellable, &error); &cancellable, &error);
if (error != NULL) { if (error != NULL) {
g_simple_async_result_take_error (res, error); g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res); g_simple_async_result_complete (res);
@ -142,6 +474,8 @@ gsecret_item_get_secret (GSecretItem *self, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data) GAsyncReadyCallback callback, gpointer user_data)
{ {
GSimpleAsyncResult *res; GSimpleAsyncResult *res;
GSecretItemPrivate *pv;
g_return_if_fail (GSECRET_IS_ITEM (self)); g_return_if_fail (GSECRET_IS_ITEM (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@ -149,7 +483,8 @@ gsecret_item_get_secret (GSecretItem *self, GCancellable *cancellable,
res = g_simple_async_result_new (G_OBJECT (self), callback, res = g_simple_async_result_new (G_OBJECT (self), callback,
user_data, gsecret_item_get_secret); user_data, gsecret_item_get_secret);
gsecret_service_ensure_session (self->pv->service, cancellable, pv = gsecret_item_private_get (self);
gsecret_service_ensure_session (pv->service, cancellable,
on_service_ensure_session, on_service_ensure_session,
g_object_ref (res)); g_object_ref (res));
@ -177,30 +512,25 @@ gsecret_item_get_secret_sync (GSecretItem *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
const gchar *session_path; GSecretSync *sync;
GSecretValue *value; GSecretValue *value;
GVariant *ret;
session_path = gsecret_service_ensure_session_sync (self->pv->service, g_return_val_if_fail (GSECRET_IS_ITEM (self), FALSE);
cancellable, error); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
if (session_path != NULL) g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return NULL;
g_assert (session_path != NULL && session_path[0] != '\0'); sync = _gsecret_sync_new ();
ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "GetSecret", g_main_context_push_thread_default (sync->context);
g_variant_new ("o", session_path),
G_DBUS_CALL_FLAGS_NONE, -1,
cancellable, error);
if (ret != NULL) { gsecret_item_get_secret (self, cancellable, _gsecret_sync_on_result, sync);
value = _gsecret_service_decode_secret (self->pv->service, ret);
if (value == NULL) { g_main_loop_run (sync->loop);
g_set_error (error, GSECRET_ERROR, GSECRET_ERROR_PROTOCOL,
_("Received invalid secret from the secret storage")); value = gsecret_item_get_secret_finish (self, sync->result, error);
}
} g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
g_object_unref (ret);
return value; return value;
} }

View File

@ -29,23 +29,34 @@ G_BEGIN_DECLS
#define GSECRET_ITEM_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), GSECRET_TYPE_ITEM, GSecretItemClass)) #define GSECRET_ITEM_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), GSECRET_TYPE_ITEM, GSecretItemClass))
typedef struct _GSecretItemClass GSecretItemClass; typedef struct _GSecretItemClass GSecretItemClass;
typedef struct _GSecretItemPrivate GSecretItemPrivate;
struct _GSecretItemClass {
GDBusProxyClass parent_class;
};
struct _GSecretItem { struct _GSecretItem {
GDBusProxy parent_instance; GDBusProxy parent_instance;
GSecretItemPrivate *pv; gpointer padding;
};
struct _GSecretItemClass {
GDBusProxyClass parent_class;
gpointer padding[4];
}; };
GType gsecret_item_get_type (void) G_GNUC_CONST; GType gsecret_item_get_type (void) G_GNUC_CONST;
#if 0 void gsecret_item_new (GSecretService *service,
GSecretItem * gsecret_item_instance (GDBusConnection *connection, const gchar *item_path,
const gchar *object_path); GCancellable *cancellable,
#endif GAsyncReadyCallback callback,
gpointer user_data);
GSecretItem * gsecret_item_new_finish (GAsyncResult *result,
GError **error);
GSecretItem * gsecret_item_new_sync (GSecretService *service,
const gchar *item_path,
GCancellable *cancellable,
GError **error);
void gsecret_item_refresh (GSecretItem *self);
void gsecret_item_delete (GSecretItem *self, void gsecret_item_delete (GSecretItem *self,
GCancellable *cancellable, GCancellable *cancellable,

View File

@ -18,45 +18,6 @@
#include <egg/egg-secure-memory.h> #include <egg/egg-secure-memory.h>
typedef struct {
GAsyncResult *result;
GMainContext *context;
GMainLoop *loop;
} SyncClosure;
static SyncClosure *
sync_closure_new (void)
{
SyncClosure *closure;
closure = g_new0 (SyncClosure, 1);
closure->context = g_main_context_new ();
closure->loop = g_main_loop_new (closure->context, FALSE);
return closure;
}
static void
sync_closure_free (gpointer data)
{
SyncClosure *closure = data;
g_clear_object (&closure->result);
g_main_loop_unref (closure->loop);
g_main_context_unref (closure->context);
}
static void
on_sync_result (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
SyncClosure *closure = user_data;
closure->result = g_object_ref (result);
g_main_loop_quit (closure->loop);
}
typedef struct { typedef struct {
const GSecretSchema *schema; const GSecretSchema *schema;
GHashTable *attributes; GHashTable *attributes;
@ -88,7 +49,7 @@ on_store_complete (GObject *source,
StoreClosure *closure = g_simple_async_result_get_op_res_gpointer (res); StoreClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GError *error = NULL; GError *error = NULL;
closure->created = gsecret_service_store_password_finish (GSECRET_SERVICE (source), closure->created = gsecret_service_store_finish (GSECRET_SERVICE (source),
result, &error); result, &error);
if (error != NULL) if (error != NULL)
g_simple_async_result_take_error (res, error); g_simple_async_result_take_error (res, error);
@ -109,7 +70,7 @@ on_store_connected (GObject *source,
service = _gsecret_service_bare_connect_finish (result, &error); service = _gsecret_service_bare_connect_finish (result, &error);
if (error == NULL) { if (error == NULL) {
gsecret_service_store_passwordv (service, closure->schema, gsecret_service_storev (service, closure->schema,
closure->attributes, closure->attributes,
closure->collection_path, closure->collection_path,
closure->label, closure->value, closure->label, closure->value,
@ -250,7 +211,7 @@ gsecret_password_storev_sync (const GSecretSchema *schema,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
SyncClosure *closure; GSecretSync *sync;
gboolean ret; gboolean ret;
g_return_val_if_fail (schema != NULL, FALSE); g_return_val_if_fail (schema != NULL, FALSE);
@ -261,18 +222,18 @@ gsecret_password_storev_sync (const GSecretSchema *schema,
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
closure = sync_closure_new (); sync = _gsecret_sync_new ();
g_main_context_push_thread_default (closure->context); g_main_context_push_thread_default (sync->context);
gsecret_password_storev (schema, collection_path, label, password, attributes, gsecret_password_storev (schema, collection_path, label, password, attributes,
cancellable, on_sync_result, closure); cancellable, _gsecret_sync_on_result, sync);
g_main_loop_run (closure->loop); g_main_loop_run (sync->loop);
ret = gsecret_password_store_finish (closure->result, error); ret = gsecret_password_store_finish (sync->result, error);
g_main_context_pop_thread_default (closure->context); g_main_context_pop_thread_default (sync->context);
sync_closure_free (closure); _gsecret_sync_free (sync);
return ret; return ret;
} }
@ -325,7 +286,7 @@ on_lookup_complete (GObject *source,
LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res); LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GError *error = NULL; GError *error = NULL;
closure->value = gsecret_service_lookup_password_finish (GSECRET_SERVICE (source), closure->value = gsecret_service_lookup_finish (GSECRET_SERVICE (source),
result, &error); result, &error);
if (error != NULL) if (error != NULL)
@ -351,7 +312,7 @@ on_lookup_connected (GObject *source,
g_simple_async_result_complete (res); g_simple_async_result_complete (res);
} else { } else {
gsecret_service_lookup_passwordv (service, closure->attributes, closure->cancellable, gsecret_service_lookupv (service, closure->attributes, closure->cancellable,
on_lookup_complete, g_object_ref (res)); on_lookup_complete, g_object_ref (res));
g_object_unref (service); g_object_unref (service);
} }
@ -440,25 +401,25 @@ gsecret_password_lookupv_sync (GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
SyncClosure *closure; GSecretSync *sync;
gchar *password; gchar *password;
g_return_val_if_fail (attributes != NULL, NULL); g_return_val_if_fail (attributes != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL);
closure = sync_closure_new (); sync = _gsecret_sync_new ();
g_main_context_push_thread_default (closure->context); g_main_context_push_thread_default (sync->context);
gsecret_password_deletev (attributes, cancellable, gsecret_password_removev (attributes, cancellable,
on_sync_result, closure); _gsecret_sync_on_result, sync);
g_main_loop_run (closure->loop); g_main_loop_run (sync->loop);
password = gsecret_password_lookup_finish (closure->result, error); password = gsecret_password_lookup_finish (sync->result, error);
g_main_context_pop_thread_default (closure->context); g_main_context_pop_thread_default (sync->context);
sync_closure_free (closure); _gsecret_sync_free (sync);
return password; return password;
} }
@ -479,7 +440,7 @@ delete_closure_free (gpointer data)
} }
void void
gsecret_password_delete (const GSecretSchema *schema, gsecret_password_remove (const GSecretSchema *schema,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data, gpointer user_data,
@ -495,7 +456,7 @@ gsecret_password_delete (const GSecretSchema *schema,
attributes = _gsecret_util_attributes_for_varargs (schema, va); attributes = _gsecret_util_attributes_for_varargs (schema, va);
va_end (va); va_end (va);
gsecret_password_deletev (attributes, cancellable, gsecret_password_removev (attributes, cancellable,
callback, user_data); callback, user_data);
g_hash_table_unref (attributes); g_hash_table_unref (attributes);
@ -510,7 +471,7 @@ on_delete_complete (GObject *source,
DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res); DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
GError *error = NULL; GError *error = NULL;
closure->deleted = gsecret_service_delete_password_finish (GSECRET_SERVICE (source), closure->deleted = gsecret_service_remove_finish (GSECRET_SERVICE (source),
result, &error); result, &error);
if (error != NULL) if (error != NULL)
g_simple_async_result_take_error (res, error); g_simple_async_result_take_error (res, error);
@ -531,7 +492,7 @@ on_delete_connect (GObject *source,
service = _gsecret_service_bare_connect_finish (result, &error); service = _gsecret_service_bare_connect_finish (result, &error);
if (error == NULL) { if (error == NULL) {
gsecret_service_delete_passwordv (service, closure->attributes, gsecret_service_removev (service, closure->attributes,
closure->cancellable, on_delete_complete, closure->cancellable, on_delete_complete,
g_object_ref (res)); g_object_ref (res));
g_object_unref (service); g_object_unref (service);
@ -545,7 +506,7 @@ on_delete_connect (GObject *source,
} }
void void
gsecret_password_deletev (GHashTable *attributes, gsecret_password_removev (GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
@ -557,7 +518,7 @@ gsecret_password_deletev (GHashTable *attributes,
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = g_simple_async_result_new (NULL, callback, user_data, res = g_simple_async_result_new (NULL, callback, user_data,
gsecret_password_deletev); gsecret_password_removev);
closure = g_slice_new0 (DeleteClosure); closure = g_slice_new0 (DeleteClosure);
closure->attributes = g_hash_table_ref (attributes); closure->attributes = g_hash_table_ref (attributes);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
@ -571,7 +532,7 @@ gsecret_password_deletev (GHashTable *attributes,
} }
gboolean gboolean
gsecret_password_delete_finish (GAsyncResult *result, gsecret_password_remove_finish (GAsyncResult *result,
GError **error) GError **error)
{ {
DeleteClosure *closure; DeleteClosure *closure;
@ -579,7 +540,7 @@ gsecret_password_delete_finish (GAsyncResult *result,
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
gsecret_password_deletev), FALSE); gsecret_password_removev), FALSE);
res = G_SIMPLE_ASYNC_RESULT (result); res = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (res, error)) if (g_simple_async_result_propagate_error (res, error))
@ -590,7 +551,7 @@ gsecret_password_delete_finish (GAsyncResult *result,
} }
gboolean gboolean
gsecret_password_delete_sync (const GSecretSchema* schema, gsecret_password_remove_sync (const GSecretSchema* schema,
GCancellable *cancellable, GCancellable *cancellable,
GError **error, GError **error,
...) ...)
@ -607,7 +568,7 @@ gsecret_password_delete_sync (const GSecretSchema* schema,
attributes = _gsecret_util_attributes_for_varargs (schema, va); attributes = _gsecret_util_attributes_for_varargs (schema, va);
va_end (va); va_end (va);
result = gsecret_password_deletev_sync (attributes, cancellable, error); result = gsecret_password_removev_sync (attributes, cancellable, error);
g_hash_table_unref (attributes); g_hash_table_unref (attributes);
@ -615,29 +576,29 @@ gsecret_password_delete_sync (const GSecretSchema* schema,
} }
gboolean gboolean
gsecret_password_deletev_sync (GHashTable *attributes, gsecret_password_removev_sync (GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
SyncClosure *closure; GSecretSync *sync;
gboolean result; gboolean result;
g_return_val_if_fail (attributes != NULL, FALSE); g_return_val_if_fail (attributes != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
closure = sync_closure_new (); sync = _gsecret_sync_new ();
g_main_context_push_thread_default (closure->context); g_main_context_push_thread_default (sync->context);
gsecret_password_deletev (attributes, cancellable, gsecret_password_removev (attributes, cancellable,
on_sync_result, closure); _gsecret_sync_on_result, sync);
g_main_loop_run (closure->loop); g_main_loop_run (sync->loop);
result = gsecret_password_delete_finish (closure->result, error); result = gsecret_password_remove_finish (sync->result, error);
g_main_context_pop_thread_default (closure->context); g_main_context_pop_thread_default (sync->context);
sync_closure_free (closure); _gsecret_sync_free (sync);
return result; return result;
} }
@ -650,4 +611,3 @@ gsecret_password_free (gpointer password)
egg_secure_strfree (password); egg_secure_strfree (password);
} }

View File

@ -79,26 +79,26 @@ gchar * gsecret_password_lookupv_sync (GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
void gsecret_password_delete (const GSecretSchema *schema, void gsecret_password_remove (const GSecretSchema *schema,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data, gpointer user_data,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
void gsecret_password_deletev (GHashTable *attributes, void gsecret_password_removev (GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
gboolean gsecret_password_delete_finish (GAsyncResult *result, gboolean gsecret_password_remove_finish (GAsyncResult *result,
GError **error); GError **error);
gboolean gsecret_password_delete_sync (const GSecretSchema* schema, gboolean gsecret_password_remove_sync (const GSecretSchema* schema,
GCancellable *cancellable, GCancellable *cancellable,
GError **error, GError **error,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
gboolean gsecret_password_deletev_sync (GHashTable *attributes, gboolean gsecret_password_removev_sync (GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);

View File

@ -21,10 +21,10 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct { typedef struct {
GVariant *in; GAsyncResult *result;
GVariant *out; GMainContext *context;
GCancellable *cancellable; GMainLoop *loop;
} GSecretParams; } GSecretSync;
#define GSECRET_SERVICE_PATH "/org/freedesktop/secrets" #define GSECRET_SERVICE_PATH "/org/freedesktop/secrets"
@ -39,10 +39,13 @@ typedef struct {
#define GSECRET_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" #define GSECRET_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
GSecretParams * _gsecret_params_new (GCancellable *cancellable, GSecretSync * _gsecret_sync_new (void);
GVariant *in);
void _gsecret_params_free (gpointer data); void _gsecret_sync_free (gpointer data);
void _gsecret_sync_on_result (GObject *source,
GAsyncResult *result,
gpointer user_data);
GSecretPrompt * _gsecret_prompt_instance (GDBusConnection *connection, GSecretPrompt * _gsecret_prompt_instance (GDBusConnection *connection,
const gchar *object_path); const gchar *object_path);
@ -51,6 +54,8 @@ gchar * _gsecret_util_parent_path (const gchar *path);
gboolean _gsecret_util_empty_path (const gchar *path); gboolean _gsecret_util_empty_path (const gchar *path);
GType _gsecret_list_get_type (void) G_GNUC_CONST;
GVariant * _gsecret_util_variant_for_attributes (GHashTable *attributes); GVariant * _gsecret_util_variant_for_attributes (GHashTable *attributes);
GHashTable * _gsecret_util_attributes_for_variant (GVariant *variant); GHashTable * _gsecret_util_attributes_for_variant (GVariant *variant);
@ -58,6 +63,17 @@ GHashTable * _gsecret_util_attributes_for_variant (GVariant *varian
GHashTable * _gsecret_util_attributes_for_varargs (const GSecretSchema *schema, GHashTable * _gsecret_util_attributes_for_varargs (const GSecretSchema *schema,
va_list va); va_list va);
void _gsecret_util_get_properties (GDBusProxy *proxy,
gpointer result_tag,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean _gsecret_util_get_properties_finish (GDBusProxy *proxy,
gpointer result_tag,
GAsyncResult *result,
GError **error);
void _gsecret_util_set_property (GDBusProxy *proxy, void _gsecret_util_set_property (GDBusProxy *proxy,
const gchar *property, const gchar *property,
GVariant *value, GVariant *value,
@ -102,6 +118,12 @@ const gchar * _gsecret_service_ensure_session_finish (GSecretService *
GCancellable **cancellable, GCancellable **cancellable,
GError **error); GError **error);
GSecretItem * _gsecret_service_find_item_instance (GSecretService *self,
const gchar *item_path);
GSecretItem * _gsecret_collection_find_item_instance (GSecretCollection *self,
const gchar *item_path);
gchar * _gsecret_value_unref_to_password (GSecretValue *value); gchar * _gsecret_value_unref_to_password (GSecretValue *value);
G_END_DECLS G_END_DECLS

View File

@ -21,10 +21,12 @@
#include <gcrypt.h> #include <gcrypt.h>
struct _GSecretPromptPrivate { typedef struct _GSecretPromptPrivate {
/* Locked by mutex */
GMutex mutex;
gint prompted; gint prompted;
GVariant *last_result; GVariant *last_result;
}; } GSecretPromptPrivate;
G_DEFINE_TYPE (GSecretPrompt, gsecret_prompt, G_TYPE_DBUS_PROXY); G_DEFINE_TYPE (GSecretPrompt, gsecret_prompt, G_TYPE_DBUS_PROXY);
@ -33,6 +35,8 @@ gsecret_prompt_init (GSecretPrompt *self)
{ {
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GSECRET_TYPE_PROMPT, self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GSECRET_TYPE_PROMPT,
GSecretPromptPrivate); GSecretPromptPrivate);
g_mutex_init (&self->pv->mutex);
} }
static void static void
@ -40,6 +44,7 @@ gsecret_prompt_finalize (GObject *obj)
{ {
GSecretPrompt *self = GSECRET_PROMPT (obj); GSecretPrompt *self = GSECRET_PROMPT (obj);
g_mutex_clear (&self->pv->mutex);
if (self->pv->last_result) if (self->pv->last_result)
g_variant_unref (self->pv->last_result); g_variant_unref (self->pv->last_result);
@ -234,8 +239,10 @@ on_prompt_completed (GDBusConnection *connection,
perform_prompt_complete (res, TRUE); perform_prompt_complete (res, TRUE);
} else { } else {
g_return_if_fail (self->pv->last_result == NULL); g_mutex_lock (&self->pv->mutex);
g_variant_get (parameters, "(bv)", &dismissed, &self->pv->last_result); g_variant_get (parameters, "(bv)", &dismissed, &self->pv->last_result);
g_mutex_unlock (&self->pv->mutex);
perform_prompt_complete (res, dismissed); perform_prompt_complete (res, dismissed);
} }
@ -265,10 +272,12 @@ on_prompt_prompted (GObject *source,
perform_prompt_complete (res, TRUE); perform_prompt_complete (res, TRUE);
} else { } else {
g_atomic_int_inc (&self->pv->prompted); g_mutex_lock (&self->pv->mutex);
closure->prompting = TRUE;
self->pv->prompted = TRUE;
g_mutex_unlock (&self->pv->mutex);
/* And now we wait for the signal */ /* And now we wait for the signal */
closure->prompting = TRUE;
} }
g_object_unref (res); g_object_unref (res);
@ -341,13 +350,18 @@ gsecret_prompt_perform (GSecretPrompt *self,
PerformClosure *closure; PerformClosure *closure;
const gchar *owner_name; const gchar *owner_name;
const gchar *object_path; const gchar *object_path;
gboolean prompted;
GDBusProxy *proxy; GDBusProxy *proxy;
gchar *window; gchar *window;
g_return_if_fail (GSECRET_IS_PROMPT (self)); g_return_if_fail (GSECRET_IS_PROMPT (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
if (g_atomic_int_get (&self->pv->prompted)) { g_mutex_lock (&self->pv->mutex);
prompted = self->pv->prompted;
g_mutex_unlock (&self->pv->mutex);
if (prompted) {
g_warning ("The prompt object has already had its prompt called."); g_warning ("The prompt object has already had its prompt called.");
return; return;
} }
@ -425,20 +439,27 @@ GVariant *
gsecret_prompt_get_result_value (GSecretPrompt *self, gsecret_prompt_get_result_value (GSecretPrompt *self,
const GVariantType *expected_type) const GVariantType *expected_type)
{ {
GVariant *last_result;
gchar *string; gchar *string;
g_return_val_if_fail (GSECRET_IS_PROMPT (self), NULL); g_return_val_if_fail (GSECRET_IS_PROMPT (self), NULL);
if (!self->pv->last_result) g_mutex_lock (&self->pv->mutex);
return NULL; if (self->pv->last_result)
last_result = g_variant_ref (self->pv->last_result);
else
last_result = NULL;
g_mutex_unlock (&self->pv->mutex);
if (expected_type && !g_variant_is_of_type (self->pv->last_result, expected_type)) { if (last_result != NULL && expected_type != NULL &&
!g_variant_is_of_type (last_result, expected_type)) {
string = g_variant_type_dup_string (expected_type); string = g_variant_type_dup_string (expected_type);
g_warning ("received unexpected result type %s from Completed signal instead of expected %s", g_warning ("received unexpected result type %s from Completed signal instead of expected %s",
g_variant_get_type_string (self->pv->last_result), string); g_variant_get_type_string (last_result), string);
g_variant_unref (last_result);
g_free (string); g_free (string);
return NULL; return NULL;
} }
return g_variant_ref (self->pv->last_result); return last_result;
} }

View File

@ -29,17 +29,16 @@ G_BEGIN_DECLS
typedef struct _GSecretPromptClass GSecretPromptClass; typedef struct _GSecretPromptClass GSecretPromptClass;
typedef struct _GSecretPromptPrivate GSecretPromptPrivate; typedef struct _GSecretPromptPrivate GSecretPromptPrivate;
struct _GSecretPromptClass {
GDBusProxyClass parent_class;
gpointer padding[8];
};
struct _GSecretPrompt { struct _GSecretPrompt {
GDBusProxy parent_instance; GDBusProxy parent_instance;
GSecretPromptPrivate *pv; GSecretPromptPrivate *pv;
}; };
struct _GSecretPromptClass {
GDBusProxyClass parent_class;
gpointer padding[8];
};
GType gsecret_prompt_get_type (void) G_GNUC_CONST; GType gsecret_prompt_get_type (void) G_GNUC_CONST;
GSecretPrompt * gsecret_prompt_instance (GSecretService *service, GSecretPrompt * gsecret_prompt_instance (GSecretService *service,

File diff suppressed because it is too large Load Diff

View File

@ -31,9 +31,17 @@ G_BEGIN_DECLS
typedef struct _GSecretServiceClass GSecretServiceClass; typedef struct _GSecretServiceClass GSecretServiceClass;
typedef struct _GSecretServicePrivate GSecretServicePrivate; typedef struct _GSecretServicePrivate GSecretServicePrivate;
struct _GSecretService {
GDBusProxy parent;
GSecretServicePrivate *pv;
};
struct _GSecretServiceClass { struct _GSecretServiceClass {
GDBusProxyClass parent_class; GDBusProxyClass parent_class;
GType collection_gtype;
GType item_gtype;
gboolean (*prompt_sync) (GSecretService *self, gboolean (*prompt_sync) (GSecretService *self,
GSecretPrompt *prompt, GSecretPrompt *prompt,
GCancellable *cancellable, GCancellable *cancellable,
@ -48,16 +56,12 @@ struct _GSecretServiceClass {
gboolean (*prompt_finish) (GSecretService *self, gboolean (*prompt_finish) (GSecretService *self,
GAsyncResult *result, GAsyncResult *result,
GError **error); GError **error);
};
struct _GSecretService { gpointer padding[16];
GDBusProxy parent_instance;
GSecretServicePrivate *pv;
}; };
GType gsecret_service_get_type (void) G_GNUC_CONST; GType gsecret_service_get_type (void) G_GNUC_CONST;
#if 0
void gsecret_service_get (GCancellable *cancellable, void gsecret_service_get (GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
@ -65,23 +69,10 @@ void gsecret_service_get (GCancellable *canc
GSecretService * gsecret_service_get_finish (GAsyncResult *result, GSecretService * gsecret_service_get_finish (GAsyncResult *result,
GError **error); GError **error);
GSecretService* gsecret_service_get_sync (GAsyncResult *result, GSecretService * gsecret_service_get_sync (GCancellable *cancellable,
GError **error); GError **error);
void gsecret_service_instance (GDBusConnection *connection, GList * gsecret_service_get_collections (GSecretService *self);
const gchar *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSecretService * gsecret_service_instance_finish (GAsyncResult *result,
GError **error);
GSecretService * gsecret_service_instance_sync (GDBusConnection *connection,
const gchar *object_path,
GCancellable *cancellable,
GError **error);
#endif
const gchar * gsecret_service_get_session_algorithms (GSecretService *self); const gchar * gsecret_service_get_session_algorithms (GSecretService *self);
@ -100,7 +91,6 @@ const gchar * gsecret_service_ensure_session_sync (GSecretService *se
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
#if 0
void gsecret_service_search (GSecretService *self, void gsecret_service_search (GSecretService *self,
GHashTable *attributes, GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
@ -119,7 +109,6 @@ gboolean gsecret_service_search_sync (GSecretService *se
GList **unlocked, GList **unlocked,
GList **locked, GList **locked,
GError **error); GError **error);
#endif
void gsecret_service_search_for_paths (GSecretService *self, void gsecret_service_search_for_paths (GSecretService *self,
GHashTable *attributes, GHashTable *attributes,
@ -170,24 +159,53 @@ GHashTable * gsecret_service_get_secrets_for_paths_sync (GSecretServ
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
#if 0 void gsecret_service_get_secrets (GSecretService *self,
GList *items,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GHashTable * gsecret_service_get_secrets_finish (GSecretService *self,
GAsyncResult *result,
GError **error);
GHashTable * gsecret_service_get_secrets_sync (GSecretService *self,
GList *items,
GCancellable *cancellable,
GError **error);
void gsecret_service_lock (GSecretService *self, void gsecret_service_lock (GSecretService *self,
GList *objects, GList *objects,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
gboolean gsecret_service_lock_finish (GSecretService *self, gint gsecret_service_lock_finish (GSecretService *self,
GAsyncResult *result, GAsyncResult *result,
GList **locked, GList **locked,
GSecretPrompt *prompt,
GError **error); GError **error);
void gsecret_service_lock_sync (GSecretService *self, gint gsecret_service_lock_sync (GSecretService *self,
GList *objects, GList *objects,
GCancellable *cancellable, GCancellable *cancellable,
GList **locked, GList **locked,
GSecretPrompt *prompt, GError **error);
gint gsecret_service_lock_paths_sync (GSecretService *self,
const gchar **paths,
GCancellable *cancellable,
gchar ***locked,
GError **error);
void gsecret_service_lock_paths (GSecretService *self,
const gchar **paths,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gint gsecret_service_lock_paths_finish (GSecretService *self,
GAsyncResult *result,
gchar ***locked,
GError **error); GError **error);
void gsecret_service_unlock (GSecretService *self, void gsecret_service_unlock (GSecretService *self,
@ -195,7 +213,17 @@ void gsecret_service_unlock (GSecretService *se
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
#endif
gint gsecret_service_unlock_finish (GSecretService *self,
GAsyncResult *result,
GList **unlocked,
GError **error);
gint gsecret_service_unlock_sync (GSecretService *self,
GList *objects,
GCancellable *cancellable,
GList **unlocked,
GError **error);
gint gsecret_service_unlock_paths_sync (GSecretService *self, gint gsecret_service_unlock_paths_sync (GSecretService *self,
const gchar **paths, const gchar **paths,
@ -225,17 +253,11 @@ void gsecret_service_prompt (GSecretService *se
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
void gsecret_service_prompt_path (GSecretService *self,
const gchar *prompt_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean gsecret_service_prompt_finish (GSecretService *self, gboolean gsecret_service_prompt_finish (GSecretService *self,
GAsyncResult *result, GAsyncResult *result,
GError **error); GError **error);
void gsecret_service_store_password (GSecretService *self, void gsecret_service_store (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
const gchar *collection_path, const gchar *collection_path,
const gchar *label, const gchar *label,
@ -245,7 +267,7 @@ void gsecret_service_store_password (GSecretService *se
gpointer user_data, gpointer user_data,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
void gsecret_service_store_passwordv (GSecretService *self, void gsecret_service_storev (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
GHashTable *attributes, GHashTable *attributes,
const gchar *collection_path, const gchar *collection_path,
@ -255,11 +277,11 @@ void gsecret_service_store_passwordv (GSecretService *se
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
gboolean gsecret_service_store_password_finish (GSecretService *self, gboolean gsecret_service_store_finish (GSecretService *self,
GAsyncResult *result, GAsyncResult *result,
GError **error); GError **error);
gboolean gsecret_service_store_password_sync (GSecretService *self, gboolean gsecret_service_store_sync (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
const gchar *collection_path, const gchar *collection_path,
const gchar *label, const gchar *label,
@ -268,7 +290,7 @@ gboolean gsecret_service_store_password_sync (GSecretService *se
GError **error, GError **error,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
gboolean gsecret_service_store_passwordv_sync (GSecretService *self, gboolean gsecret_service_storev_sync (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
GHashTable *attributes, GHashTable *attributes,
const gchar *collection_path, const gchar *collection_path,
@ -277,30 +299,30 @@ gboolean gsecret_service_store_passwordv_sync (GSecretService *se
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
void gsecret_service_lookup_password (GSecretService *self, void gsecret_service_lookup (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data, gpointer user_data,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
void gsecret_service_lookup_passwordv (GSecretService *self, void gsecret_service_lookupv (GSecretService *self,
GHashTable *attributes, GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
GSecretValue * gsecret_service_lookup_password_finish (GSecretService *self, GSecretValue * gsecret_service_lookup_finish (GSecretService *self,
GAsyncResult *result, GAsyncResult *result,
GError **error); GError **error);
GSecretValue * gsecret_service_lookup_password_sync (GSecretService *self, GSecretValue * gsecret_service_lookup_sync (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
GCancellable *cancellable, GCancellable *cancellable,
GError **error, GError **error,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
GSecretValue * gsecret_service_lookup_passwordv_sync (GSecretService *self, GSecretValue * gsecret_service_lookupv_sync (GSecretService *self,
GHashTable *attributes, GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
@ -320,46 +342,34 @@ gboolean gsecret_service_delete_path_sync (GSecretService *se
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
void gsecret_service_delete_password (GSecretService *self, void gsecret_service_remove (GSecretService *self,
const GSecretSchema *schema, const GSecretSchema *schema,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data, gpointer user_data,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
void gsecret_service_delete_passwordv (GSecretService *self, void gsecret_service_removev (GSecretService *self,
GHashTable *attributes, GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
gboolean gsecret_service_delete_password_finish (GSecretService *self, gboolean gsecret_service_remove_finish (GSecretService *self,
GAsyncResult *result, GAsyncResult *result,
GError **error); GError **error);
gboolean gsecret_service_delete_password_sync (GSecretService *self, gboolean gsecret_service_remove_sync (GSecretService *self,
const GSecretSchema* schema, const GSecretSchema* schema,
GCancellable *cancellable, GCancellable *cancellable,
GError **error, GError **error,
...) G_GNUC_NULL_TERMINATED; ...) G_GNUC_NULL_TERMINATED;
gboolean gsecret_service_delete_passwordv_sync (GSecretService *self, gboolean gsecret_service_removev_sync (GSecretService *self,
GHashTable *attributes, GHashTable *attributes,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
#if 0
GSecretCollection* gsecret_service_read_alias (GSecretService *self,
const gchar *alias,
GError **error);
GSecretCollection* gsecret_service_set_alias (GSecretService *self,
const gchar *alias,
GSecretCollection *collection,
GError **error);
#endif
G_END_DECLS G_END_DECLS
#endif /* __G_SERVICE_H___ */ #endif /* __GSECRET_SERVICE_H___ */

View File

@ -17,6 +17,40 @@
#include <string.h> #include <string.h>
static void
list_unref_free (GList *reflist)
{
GList *l;
for (l = reflist; l; l = g_list_next (l)) {
g_return_if_fail (G_IS_OBJECT (l->data));
g_object_unref (l->data);
}
g_list_free (reflist);
}
static GList *
list_ref_copy (GList *reflist)
{
GList *l, *copy = g_list_copy (reflist);
for (l = copy; l; l = g_list_next (l)) {
g_return_val_if_fail (G_IS_OBJECT (l->data), NULL);
g_object_ref (l->data);
}
return copy;
}
GType
_gsecret_list_get_type (void)
{
static GType type = 0;
if (!type)
type = g_boxed_type_register_static ("GSecretObjectList",
(GBoxedCopyFunc)list_ref_copy,
(GBoxedFreeFunc)list_unref_free);
return type;
}
GQuark GQuark
gsecret_error_get_quark (void) gsecret_error_get_quark (void)
{ {
@ -31,32 +65,6 @@ gsecret_error_get_quark (void)
return quark; return quark;
} }
GSecretParams *
_gsecret_params_new (GCancellable *cancellable,
GVariant *in)
{
GSecretParams *params;
params = g_slice_new0 (GSecretParams);
params->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
params->in = g_variant_ref_sink (in);
return params;
}
void
_gsecret_params_free (gpointer data)
{
GSecretParams *params = data;
g_clear_object (&params->cancellable);
if (params->in)
g_variant_unref (params->in);
if (params->out)
g_variant_unref (params->out);
g_slice_free (GSecretParams, params);
}
gchar * gchar *
_gsecret_util_parent_path (const gchar *path) _gsecret_util_parent_path (const gchar *path)
{ {
@ -184,6 +192,103 @@ _gsecret_util_attributes_for_varargs (const GSecretSchema *schema,
return attributes; return attributes;
} }
static void
process_get_all_reply (GDBusProxy *proxy,
GVariant *retval)
{
const gchar *invalidated_properties[1] = { NULL };
GVariant *changed_properties;
GVariantIter *iter;
GVariant *value;
gchar *key;
if (!g_variant_is_of_type (retval, G_VARIANT_TYPE ("(a{sv})"))) {
g_warning ("Value for GetAll reply with type `%s' does not match `(a{sv})'",
g_variant_get_type_string (retval));
return;
}
g_variant_get (retval, "(a{sv})", &iter);
while (g_variant_iter_loop (iter, "{sv}", &key, &value))
g_dbus_proxy_set_cached_property (proxy, key, value);
g_variant_iter_free (iter);
g_variant_get (retval, "(@a{sv})", &changed_properties);
g_signal_emit_by_name (proxy, "properties-changed",
changed_properties, invalidated_properties);
g_variant_unref (changed_properties);
}
static void
on_get_properties (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (result);
GDBusProxy *proxy = G_DBUS_PROXY (g_async_result_get_source_object (user_data));
GError *error = NULL;
GVariant *retval;
retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
if (error == NULL)
process_get_all_reply (proxy, retval);
else
g_simple_async_result_take_error (res, error);
if (retval != NULL)
g_variant_unref (retval);
g_simple_async_result_complete (res);
g_object_unref (proxy);
g_object_unref (res);
}
void
_gsecret_util_get_properties (GDBusProxy *proxy,
gpointer result_tag,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = g_simple_async_result_new (G_OBJECT (proxy), callback, user_data, result_tag);
g_dbus_connection_call (g_dbus_proxy_get_connection (proxy),
g_dbus_proxy_get_name (proxy),
g_dbus_proxy_get_object_path (proxy),
"org.freedesktop.DBus.Properties", "GetAll",
g_variant_new ("(s)", g_dbus_proxy_get_interface_name (proxy)),
G_VARIANT_TYPE ("(a{sv})"),
G_DBUS_CALL_FLAGS_NONE, -1,
cancellable, on_get_properties,
g_object_ref (res));
g_object_unref (res);
}
gboolean
_gsecret_util_get_properties_finish (GDBusProxy *proxy,
gpointer result_tag,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *res;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (proxy), result_tag), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
res = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (res, error))
return FALSE;
return TRUE;
}
static void static void
on_set_property (GObject *source, on_set_property (GObject *source,
GAsyncResult *result, GAsyncResult *result,
@ -254,7 +359,6 @@ _gsecret_util_set_property_finish (GDBusProxy *proxy,
return g_simple_async_result_get_op_res_gboolean (res); return g_simple_async_result_get_op_res_gboolean (res);
} }
gboolean gboolean
_gsecret_util_set_property_sync (GDBusProxy *proxy, _gsecret_util_set_property_sync (GDBusProxy *proxy,
const gchar *property, const gchar *property,
@ -285,3 +389,37 @@ _gsecret_util_set_property_sync (GDBusProxy *proxy,
return (retval != NULL); return (retval != NULL);
} }
GSecretSync *
_gsecret_sync_new (void)
{
GSecretSync *sync;
sync = g_new0 (GSecretSync, 1);
sync->context = g_main_context_new ();
sync->loop = g_main_loop_new (sync->context, FALSE);
return sync;
}
void
_gsecret_sync_free (gpointer data)
{
GSecretSync *sync = data;
g_clear_object (&sync->result);
g_main_loop_unref (sync->loop);
g_main_context_unref (sync->context);
}
void
_gsecret_sync_on_result (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSecretSync *sync = user_data;
g_assert (sync->result == NULL);
sync->result = g_object_ref (result);
g_main_loop_quit (sync->loop);
}

View File

@ -87,7 +87,7 @@ test_delete_sync (Test *test,
GError *error = NULL; GError *error = NULL;
gboolean ret; gboolean ret;
ret = gsecret_password_delete_sync (&DELETE_SCHEMA, NULL, &error, ret = gsecret_password_remove_sync (&DELETE_SCHEMA, NULL, &error,
"even", FALSE, "even", FALSE,
"string", "one", "string", "one",
"number", 1, "number", 1,
@ -105,7 +105,7 @@ test_delete_async (Test *test,
GAsyncResult *result = NULL; GAsyncResult *result = NULL;
gboolean ret; gboolean ret;
gsecret_password_delete (&DELETE_SCHEMA, NULL, gsecret_password_remove (&DELETE_SCHEMA, NULL,
on_complete_get_result, &result, on_complete_get_result, &result,
"even", FALSE, "even", FALSE,
"string", "one", "string", "one",
@ -116,7 +116,7 @@ test_delete_async (Test *test,
egg_test_wait (); egg_test_wait ();
ret = gsecret_password_delete_finish (result, &error); ret = gsecret_password_remove_finish (result, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_assert (ret == TRUE); g_assert (ret == TRUE);

View File

@ -385,12 +385,15 @@ test_service_path (Test *test,
{ {
GError *error = NULL; GError *error = NULL;
GAsyncResult *result = NULL; GAsyncResult *result = NULL;
GSecretPrompt *prompt;
gboolean ret; gboolean ret;
gsecret_service_prompt_path (test->service, "/org/freedesktop/secrets/prompts/simple", prompt = gsecret_prompt_instance (test->service, "/org/freedesktop/secrets/prompts/simple");
NULL, on_async_result, &result);
gsecret_service_prompt (test->service, prompt, NULL, on_async_result, &result);
g_assert (result == NULL); g_assert (result == NULL);
g_object_unref (prompt);
egg_test_wait (); egg_test_wait ();
ret = gsecret_service_prompt_finish (test->service, result, &error); ret = gsecret_service_prompt_finish (test->service, result, &error);

View File

@ -523,7 +523,7 @@ test_delete_password_sync (Test *test,
GError *error = NULL; GError *error = NULL;
gboolean ret; gboolean ret;
ret = gsecret_service_delete_password_sync (test->service, &DELETE_SCHEMA, NULL, &error, ret = gsecret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error,
"even", FALSE, "even", FALSE,
"string", "one", "string", "one",
"number", 1, "number", 1,
@ -541,7 +541,7 @@ test_delete_password_async (Test *test,
GAsyncResult *result = NULL; GAsyncResult *result = NULL;
gboolean ret; gboolean ret;
gsecret_service_delete_password (test->service, &DELETE_SCHEMA, NULL, gsecret_service_remove (test->service, &DELETE_SCHEMA, NULL,
on_complete_get_result, &result, on_complete_get_result, &result,
"even", FALSE, "even", FALSE,
"string", "one", "string", "one",
@ -552,7 +552,7 @@ test_delete_password_async (Test *test,
egg_test_wait (); egg_test_wait ();
ret = gsecret_service_delete_password_finish (test->service, result, &error); ret = gsecret_service_remove_finish (test->service, result, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_assert (ret == TRUE); g_assert (ret == TRUE);
@ -566,7 +566,7 @@ test_delete_password_locked (Test *test,
GError *error = NULL; GError *error = NULL;
gboolean ret; gboolean ret;
ret = gsecret_service_delete_password_sync (test->service, &DELETE_SCHEMA, NULL, &error, ret = gsecret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error,
"even", FALSE, "even", FALSE,
"string", "three", "string", "three",
"number", 3, "number", 3,
@ -584,7 +584,7 @@ test_delete_password_no_match (Test *test,
gboolean ret; gboolean ret;
/* Won't match anything */ /* Won't match anything */
ret = gsecret_service_delete_password_sync (test->service, &DELETE_SCHEMA, NULL, &error, ret = gsecret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error,
"even", TRUE, "even", TRUE,
"string", "one", "string", "one",
NULL); NULL);