libsecret/library/gsecret-item.c
2011-09-25 18:39:03 +02:00

299 lines
10 KiB
C

/* GSecret - GLib wrapper for Secret Service
*
* Copyright 2011 Collabora Ltd.
*
* 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-item.h"
#include "gsecret-private.h"
#include "gsecret-service.h"
#include "gsecret-types.h"
#include "gsecret-value.h"
#include <glib/gi18n-lib.h>
struct _GSecretItemPrivate {
GSecretService *service;
};
G_DEFINE_TYPE (GSecretItem, gsecret_item, G_TYPE_DBUS_PROXY);
static void
gsecret_item_init (GSecretItem *self)
{
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GSECRET_TYPE_ITEM, GSecretItemPrivate);
}
static void
gsecret_item_class_init (GSecretItemClass *klass)
{
}
static void
on_item_delete_ready (GObject *source, GAsyncResult *result, gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
GError *error = NULL;
GVariant *ret;
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
result, &error);
if (ret == NULL)
g_simple_async_result_take_error (res, error);
else
g_variant_unref (ret);
g_simple_async_result_complete (res);
g_object_unref (res);
}
void
gsecret_item_delete (GSecretItem *self, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
const gchar *object_path;
gchar *collection_path;
GSimpleAsyncResult *res;
g_return_if_fail (GSECRET_IS_ITEM (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = g_simple_async_result_new (G_OBJECT (self), callback,
user_data, gsecret_item_delete);
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
collection_path = _gsecret_util_parent_path (object_path);
g_dbus_connection_call (g_dbus_proxy_get_connection (G_DBUS_PROXY (self)),
g_dbus_proxy_get_name (G_DBUS_PROXY (self)),
collection_path, GSECRET_COLLECTION_INTERFACE,
"Delete", NULL, NULL,
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
cancellable, on_item_delete_ready, res);
g_free (collection_path);
}
gboolean
gsecret_item_delete_finish (GSecretItem *self, GAsyncResult *result,
GError **error)
{
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 (g_simple_async_result_is_valid (result,
G_OBJECT (self), gsecret_item_delete), FALSE);
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
error))
return FALSE;
return TRUE;
}
gboolean
gsecret_item_delete_sync (GSecretItem *self, GCancellable *cancellable,
GError **error)
{
const gchar *object_path;
gchar *collection_path;
GVariant *ret;
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 (error == NULL || *error == NULL, FALSE);
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
collection_path = _gsecret_util_parent_path (object_path);
ret = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (self)),
g_dbus_proxy_get_name (G_DBUS_PROXY (self)),
collection_path, GSECRET_COLLECTION_INTERFACE,
"Delete", NULL, NULL,
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
cancellable, error);
g_free (collection_path);
if (ret != NULL) {
g_variant_unref (ret);
return TRUE;
}
return FALSE;
}
static void
on_item_get_secret_ready (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;
GSecretValue *value;
GVariant *ret;
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
if (error == NULL) {
value = _gsecret_service_decode_secret (self->pv->service, ret);
if (value == NULL) {
g_set_error (&error, GSECRET_ERROR, GSECRET_ERROR_PROTOCOL,
_("Received invalid secret from the secret storage"));
}
g_object_unref (ret);
}
if (error != NULL)
g_simple_async_result_take_error (res, error);
else
g_simple_async_result_set_op_res_gpointer (res, value,
gsecret_value_unref);
g_simple_async_result_complete (res);
g_object_unref (res);
}
static void
on_service_ensure_session (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;
GCancellable *cancellable = NULL;
const gchar *session_path;
session_path = _gsecret_service_ensure_session_finish (self->pv->service,
result, &cancellable, &error);
if (error != NULL) {
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
} else {
g_assert (session_path != NULL && session_path[0] != '\0');
g_dbus_proxy_call (G_DBUS_PROXY (self), "GetSecret",
g_variant_new ("o", session_path),
G_DBUS_CALL_FLAGS_NONE, -1, cancellable,
on_item_get_secret_ready, g_object_ref (res));
}
g_clear_object (&cancellable);
g_object_unref (res);
}
void
gsecret_item_get_secret (GSecretItem *self, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GSimpleAsyncResult *res;
g_return_if_fail (GSECRET_IS_ITEM (self));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = g_simple_async_result_new (G_OBJECT (self), callback,
user_data, gsecret_item_get_secret);
gsecret_service_ensure_session (self->pv->service, cancellable,
on_service_ensure_session,
g_object_ref (res));
g_object_unref (res);
}
GSecretValue*
gsecret_item_get_secret_finish (GSecretItem *self, GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *res;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
gsecret_item_get_secret), NULL);
res = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (res, error))
return NULL;
return gsecret_value_ref (g_simple_async_result_get_op_res_gpointer (res));
}
GSecretValue*
gsecret_item_get_secret_sync (GSecretItem *self,
GCancellable *cancellable,
GError **error)
{
const gchar *session_path;
GSecretValue *value;
GVariant *ret;
session_path = gsecret_service_ensure_session_sync (self->pv->service,
cancellable, error);
if (session_path != NULL)
return NULL;
g_assert (session_path != NULL && session_path[0] != '\0');
ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "GetSecret",
g_variant_new ("o", session_path),
G_DBUS_CALL_FLAGS_NONE, -1,
cancellable, error);
if (ret != NULL) {
value = _gsecret_service_decode_secret (self->pv->service, ret);
if (value == NULL) {
g_set_error (error, GSECRET_ERROR, GSECRET_ERROR_PROTOCOL,
_("Received invalid secret from the secret storage"));
}
}
g_object_unref (ret);
return value;
}
#ifdef UNIMPLEMENTED
GHashTable* gsecret_item_get_attributes (GSecretItem *self);
void gsecret_item_set_attributes (GSecretItem *self,
GHashTable *attributes,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean gsecret_item_set_attributes_finish (GSecretItem *self,
GAsyncResult *result,
GError **error);
void gsecret_item_set_attributes_sync (GSecretItem *self,
GHashTable *attributes,
GCancellable *cancellable,
GError **error);
const gchar* gsecret_item_get_label (GSecretItem *self);
void gsecret_item_set_label (GSecretItem *self,
const gchar *label,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean gsecret_item_set_label_finish (GSecretItem *self,
GAsyncResult *result,
GError **error);
void gsecret_item_set_label_sync (GSecretItem *self,
const gchar *label,
GCancellable *cancellable,
GError **error);
gboolean gsecret_item_get_locked (GSecretItem *self);
guint64 gsecret_item_get_created (GSecretItem *self);
guint64 gsecret_item_get_modified (GSecretItem *self);
#endif /* UNIMPLEMENTED */