mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2025-01-03 02:28:53 +00:00
Update the "Locked" property of items/collections on lock/unlock
* Make sure this property is kept in sync so it can be used immediately in the logic to retrieve secrets or other stuff. * We don't wait for a PropertiesChanged, which may come later
This commit is contained in:
parent
012ed7d620
commit
9c44ab0fa2
@ -367,179 +367,96 @@ _secret_service_decode_get_secrets_all (SecretService *self,
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GCancellable *cancellable;
|
||||
SecretPrompt *prompt;
|
||||
GHashTable *objects;
|
||||
GPtrArray *xlocked;
|
||||
gchar **xlocked;
|
||||
guint count;
|
||||
gboolean locking;
|
||||
} XlockClosure;
|
||||
|
||||
static void
|
||||
xlock_closure_free (gpointer data)
|
||||
{
|
||||
XlockClosure *closure = data;
|
||||
g_clear_object (&closure->cancellable);
|
||||
g_clear_object (&closure->prompt);
|
||||
if (closure->xlocked)
|
||||
g_ptr_array_unref (closure->xlocked);
|
||||
if (closure->objects)
|
||||
g_hash_table_unref (closure->objects);
|
||||
g_strfreev (closure->xlocked);
|
||||
g_hash_table_unref (closure->objects);
|
||||
g_slice_free (XlockClosure, closure);
|
||||
}
|
||||
|
||||
static void
|
||||
on_xlock_prompted (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
on_xlock_paths (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
|
||||
XlockClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
|
||||
SecretService *self = SECRET_SERVICE (source);
|
||||
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
|
||||
XlockClosure *xlock = g_simple_async_result_get_op_res_gpointer (async);
|
||||
GVariant *lockval;
|
||||
GDBusProxy *object;
|
||||
GError *error = NULL;
|
||||
GVariantIter iter;
|
||||
GVariant *retval;
|
||||
gchar *path;
|
||||
gint i;
|
||||
|
||||
retval = secret_service_prompt_finish (self, result, G_VARIANT_TYPE ("ao"), &error);
|
||||
if (error != NULL)
|
||||
g_simple_async_result_take_error (res, error);
|
||||
xlock->count = _secret_service_xlock_paths_finish (SECRET_SERVICE (source), result,
|
||||
&xlock->xlocked, &error);
|
||||
|
||||
if (retval != NULL) {
|
||||
g_variant_iter_init (&iter, retval);
|
||||
while (g_variant_iter_loop (&iter, "o", &path))
|
||||
g_ptr_array_add (closure->xlocked, g_strdup (path));
|
||||
g_variant_unref (retval);
|
||||
}
|
||||
if (error == NULL) {
|
||||
/*
|
||||
* After a lock or unlock we want the Locked property to immediately
|
||||
* reflect the new state, and not have to wait for a PropertiesChanged
|
||||
* signal to be processed later.
|
||||
*/
|
||||
|
||||
g_simple_async_result_complete (res);
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static void
|
||||
on_xlock_called (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
|
||||
XlockClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
|
||||
SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
|
||||
const gchar *prompt = NULL;
|
||||
gchar **xlocked = NULL;
|
||||
GError *error = NULL;
|
||||
GVariant *retval;
|
||||
guint i;
|
||||
|
||||
retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
|
||||
if (error != NULL) {
|
||||
g_simple_async_result_take_error (res, error);
|
||||
g_simple_async_result_complete (res);
|
||||
lockval = g_variant_ref_sink (g_variant_new_boolean (xlock->locking));
|
||||
for (i = 0; xlock->xlocked[i] != NULL; i++) {
|
||||
object = g_hash_table_lookup (xlock->objects, xlock->xlocked[i]);
|
||||
if (object != NULL)
|
||||
g_dbus_proxy_set_cached_property (object, "Locked", lockval);
|
||||
}
|
||||
g_variant_unref (lockval);
|
||||
|
||||
} else {
|
||||
g_variant_get (retval, "(^ao&o)", &xlocked, &prompt);
|
||||
|
||||
if (_secret_util_empty_path (prompt)) {
|
||||
for (i = 0; xlocked[i]; i++)
|
||||
g_ptr_array_add (closure->xlocked, g_strdup (xlocked[i]));
|
||||
g_simple_async_result_complete (res);
|
||||
|
||||
} else {
|
||||
closure->prompt = _secret_prompt_instance (self, prompt);
|
||||
secret_service_prompt (self, closure->prompt, closure->cancellable,
|
||||
on_xlock_prompted, g_object_ref (res));
|
||||
}
|
||||
|
||||
g_strfreev (xlocked);
|
||||
g_variant_unref (retval);
|
||||
g_simple_async_result_take_error (async, error);
|
||||
}
|
||||
|
||||
g_object_unref (self);
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static GSimpleAsyncResult *
|
||||
service_xlock_paths_async (SecretService *self,
|
||||
const gchar *method,
|
||||
const gchar **paths,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
XlockClosure *closure;
|
||||
|
||||
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
|
||||
service_xlock_paths_async);
|
||||
closure = g_slice_new0 (XlockClosure);
|
||||
closure->cancellable = cancellable ? g_object_ref (cancellable) : cancellable;
|
||||
closure->xlocked = g_ptr_array_new_with_free_func (g_free);
|
||||
g_simple_async_result_set_op_res_gpointer (res, closure, xlock_closure_free);
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY (self), method,
|
||||
g_variant_new ("(@ao)", g_variant_new_objv (paths, -1)),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
|
||||
cancellable, on_xlock_called, g_object_ref (res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gint
|
||||
service_xlock_paths_finish (SecretService *self,
|
||||
GAsyncResult *result,
|
||||
gchar ***xlocked,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
XlockClosure *closure;
|
||||
gint count;
|
||||
|
||||
res = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (res, error))
|
||||
return -1;
|
||||
|
||||
closure = g_simple_async_result_get_op_res_gpointer (res);
|
||||
count = closure->xlocked->len;
|
||||
|
||||
if (xlocked != NULL) {
|
||||
g_ptr_array_add (closure->xlocked, NULL);
|
||||
*xlocked = (gchar **)g_ptr_array_free (closure->xlocked, FALSE);
|
||||
closure->xlocked = NULL;
|
||||
}
|
||||
|
||||
return count;
|
||||
g_simple_async_result_complete (async);
|
||||
g_object_unref (async);
|
||||
}
|
||||
|
||||
static void
|
||||
service_xlock_async (SecretService *self,
|
||||
const gchar *method,
|
||||
gboolean locking,
|
||||
GList *objects,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
XlockClosure *closure;
|
||||
GHashTable *table;
|
||||
GSimpleAsyncResult *async;
|
||||
XlockClosure *xlock;
|
||||
GPtrArray *paths;
|
||||
const gchar *path;
|
||||
GList *l;
|
||||
|
||||
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
paths = g_ptr_array_new ();
|
||||
async = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
|
||||
service_xlock_async);
|
||||
xlock = g_slice_new0 (XlockClosure);
|
||||
xlock->objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
xlock->locking = locking;
|
||||
|
||||
paths = g_ptr_array_new ();
|
||||
for (l = objects; l != NULL; l = g_list_next (l)) {
|
||||
path = g_dbus_proxy_get_object_path (l->data);
|
||||
g_ptr_array_add (paths, (gpointer)path);
|
||||
g_hash_table_insert (table, g_strdup (path), g_object_ref (l->data));
|
||||
g_hash_table_insert (xlock->objects, g_strdup (path), g_object_ref (l->data));
|
||||
}
|
||||
g_ptr_array_add (paths, NULL);
|
||||
|
||||
res = service_xlock_paths_async (self, method, (const gchar **)paths->pdata,
|
||||
cancellable, callback, user_data);
|
||||
g_simple_async_result_set_op_res_gpointer (async, xlock, xlock_closure_free);
|
||||
|
||||
closure = g_simple_async_result_get_op_res_gpointer (res);
|
||||
closure->objects = table;
|
||||
_secret_service_xlock_paths_async (self, locking ? "Lock" : "Unlock",
|
||||
(const gchar **)paths->pdata,
|
||||
cancellable, on_xlock_paths,
|
||||
g_object_ref (async));
|
||||
|
||||
g_ptr_array_free (paths, TRUE);
|
||||
g_object_unref (res);
|
||||
g_object_unref (async);
|
||||
}
|
||||
|
||||
static gint
|
||||
@ -548,31 +465,28 @@ service_xlock_finish (SecretService *self,
|
||||
GList **xlocked,
|
||||
GError **error)
|
||||
{
|
||||
XlockClosure *closure;
|
||||
gchar **paths = NULL;
|
||||
GObject *object;
|
||||
gint count;
|
||||
guint i;
|
||||
GSimpleAsyncResult *async;
|
||||
XlockClosure *xlock;
|
||||
GDBusProxy *object;
|
||||
gint i;
|
||||
|
||||
count = service_xlock_paths_finish (self, result,
|
||||
xlocked ? &paths : NULL,
|
||||
error);
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), service_xlock_async), -1);
|
||||
|
||||
if (count > 0 && xlocked) {
|
||||
closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
|
||||
async = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (async, error))
|
||||
return -1;
|
||||
|
||||
xlock = g_simple_async_result_get_op_res_gpointer (async);
|
||||
if (xlocked) {
|
||||
*xlocked = NULL;
|
||||
|
||||
for (i = 0; paths[i] != NULL; i++) {
|
||||
object = g_hash_table_lookup (closure->objects, paths[i]);
|
||||
for (i = 0; xlock->xlocked[i] != NULL; i++) {
|
||||
object = g_hash_table_lookup (xlock->objects, xlock->xlocked[i]);
|
||||
if (object != NULL)
|
||||
*xlocked = g_list_prepend (*xlocked, g_object_ref (object));
|
||||
}
|
||||
|
||||
*xlocked = g_list_reverse (*xlocked);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
return xlock->count;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -606,7 +520,7 @@ secret_service_lock (SecretService *self,
|
||||
g_return_if_fail (SECRET_IS_SERVICE (self));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
service_xlock_async (self, "Lock", objects, cancellable, callback, user_data);
|
||||
service_xlock_async (self, TRUE, objects, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -631,8 +545,8 @@ secret_service_lock_finish (SecretService *self,
|
||||
GList **locked,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||
|
||||
return service_xlock_finish (self, result, locked, error);
|
||||
}
|
||||
@ -722,7 +636,7 @@ secret_service_unlock (SecretService *self,
|
||||
g_return_if_fail (SECRET_IS_SERVICE (self));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
service_xlock_async (self, "Unlock", objects, cancellable, callback, user_data);
|
||||
service_xlock_async (self, FALSE, objects, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -749,8 +663,6 @@ secret_service_unlock_finish (SecretService *self,
|
||||
{
|
||||
g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
|
||||
service_xlock_paths_async), -1);
|
||||
|
||||
return service_xlock_finish (self, result, unlocked, error);
|
||||
}
|
||||
|
@ -569,7 +569,6 @@ secret_service_get_secrets_for_paths_sync (SecretService *self,
|
||||
typedef struct {
|
||||
GCancellable *cancellable;
|
||||
SecretPrompt *prompt;
|
||||
GHashTable *objects;
|
||||
GPtrArray *xlocked;
|
||||
} XlockClosure;
|
||||
|
||||
@ -581,8 +580,6 @@ xlock_closure_free (gpointer data)
|
||||
g_clear_object (&closure->prompt);
|
||||
if (closure->xlocked)
|
||||
g_ptr_array_unref (closure->xlocked);
|
||||
if (closure->objects)
|
||||
g_hash_table_unref (closure->objects);
|
||||
g_slice_free (XlockClosure, closure);
|
||||
}
|
||||
|
||||
@ -655,19 +652,19 @@ on_xlock_called (GObject *source,
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static GSimpleAsyncResult *
|
||||
service_xlock_paths_async (SecretService *self,
|
||||
const gchar *method,
|
||||
const gchar **paths,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
void
|
||||
_secret_service_xlock_paths_async (SecretService *self,
|
||||
const gchar *method,
|
||||
const gchar **paths,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
XlockClosure *closure;
|
||||
|
||||
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
|
||||
service_xlock_paths_async);
|
||||
_secret_service_xlock_paths_async);
|
||||
closure = g_slice_new0 (XlockClosure);
|
||||
closure->cancellable = cancellable ? g_object_ref (cancellable) : cancellable;
|
||||
closure->xlocked = g_ptr_array_new_with_free_func (g_free);
|
||||
@ -678,14 +675,14 @@ service_xlock_paths_async (SecretService *self,
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
|
||||
cancellable, on_xlock_called, g_object_ref (res));
|
||||
|
||||
return res;
|
||||
g_object_unref (res);
|
||||
}
|
||||
|
||||
static gint
|
||||
service_xlock_paths_finish (SecretService *self,
|
||||
GAsyncResult *result,
|
||||
gchar ***xlocked,
|
||||
GError **error)
|
||||
gint
|
||||
_secret_service_xlock_paths_finish (SecretService *self,
|
||||
GAsyncResult *result,
|
||||
gchar ***xlocked,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
XlockClosure *closure;
|
||||
@ -792,16 +789,12 @@ secret_service_lock_paths (SecretService *self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
|
||||
g_return_if_fail (SECRET_IS_SERVICE (self));
|
||||
g_return_if_fail (paths != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
res = service_xlock_paths_async (self, "Lock", paths, cancellable,
|
||||
callback, user_data);
|
||||
|
||||
g_object_unref (res);
|
||||
_secret_service_xlock_paths_async (self, "Lock", paths, cancellable,
|
||||
callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -831,7 +824,7 @@ secret_service_lock_paths_finish (SecretService *self,
|
||||
g_return_val_if_fail (locked != NULL, -1);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||
|
||||
return service_xlock_paths_finish (self, result, locked, error);
|
||||
return _secret_service_xlock_paths_finish (self, result, locked, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -920,17 +913,13 @@ secret_service_unlock_paths (SecretService *self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *res;
|
||||
|
||||
g_return_if_fail (SECRET_IS_SERVICE (self));
|
||||
g_return_if_fail (paths != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
res = service_xlock_paths_async (self, "Unlock",
|
||||
paths, cancellable,
|
||||
callback, user_data);
|
||||
|
||||
g_object_unref (res);
|
||||
_secret_service_xlock_paths_async (self, "Unlock",
|
||||
paths, cancellable,
|
||||
callback, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -959,8 +948,8 @@ secret_service_unlock_paths_finish (SecretService *self,
|
||||
g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||
|
||||
return service_xlock_paths_finish (self, result,
|
||||
unlocked, error);
|
||||
return _secret_service_xlock_paths_finish (self, result,
|
||||
unlocked, error);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -145,6 +145,18 @@ SecretValue * _secret_service_decode_get_secrets_first (SecretService *se
|
||||
GHashTable * _secret_service_decode_get_secrets_all (SecretService *self,
|
||||
GVariant *out);
|
||||
|
||||
void _secret_service_xlock_paths_async (SecretService *self,
|
||||
const gchar *method,
|
||||
const gchar **paths,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
gint _secret_service_xlock_paths_finish (SecretService *self,
|
||||
GAsyncResult *result,
|
||||
gchar ***xlocked,
|
||||
GError **error);
|
||||
|
||||
SecretItem * _secret_collection_find_item_instance (SecretCollection *self,
|
||||
const gchar *item_path);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user