mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2025-01-03 02:28:53 +00:00
Try to unlock locked collection when storing an item
And add tests to verify this behavior. https://bugzilla.gnome.org/show_bug.cgi?id=693723
This commit is contained in:
parent
6ebec3f7fd
commit
0e9870bd35
@ -958,6 +958,7 @@ typedef struct {
|
||||
SecretValue *value;
|
||||
GHashTable *properties;
|
||||
gboolean created_collection;
|
||||
gboolean unlocked_collection;
|
||||
} StoreClosure;
|
||||
|
||||
static void
|
||||
@ -1004,6 +1005,31 @@ on_store_keyring (GObject *source,
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
on_store_unlock (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
|
||||
StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
|
||||
SecretService *service = SECRET_SERVICE (source);
|
||||
GError *error = NULL;
|
||||
|
||||
secret_service_unlock_dbus_paths_finish (service, result, NULL, &error);
|
||||
if (error == NULL) {
|
||||
store->unlocked_collection = TRUE;
|
||||
secret_service_create_item_dbus_path (service, store->collection_path,
|
||||
store->properties, store->value,
|
||||
SECRET_ITEM_CREATE_REPLACE, store->cancellable,
|
||||
on_store_create, g_object_ref (async));
|
||||
} else {
|
||||
g_simple_async_result_take_error (async, error);
|
||||
g_simple_async_result_complete (async);
|
||||
}
|
||||
|
||||
g_object_unref (async);
|
||||
}
|
||||
|
||||
static void
|
||||
on_store_create (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@ -1033,6 +1059,12 @@ on_store_create (GObject *source,
|
||||
g_hash_table_unref (properties);
|
||||
g_error_free (error);
|
||||
|
||||
} else if (!store->unlocked_collection &&
|
||||
g_error_matches (error, SECRET_ERROR, SECRET_ERROR_IS_LOCKED)) {
|
||||
const gchar *paths[2] = { store->collection_path, NULL };
|
||||
secret_service_unlock_dbus_paths (service, paths, store->cancellable,
|
||||
on_store_unlock, g_object_ref (async));
|
||||
g_error_free (error);
|
||||
} else {
|
||||
if (error != NULL)
|
||||
g_simple_async_result_take_error (async, error);
|
||||
|
@ -392,6 +392,8 @@ class SecretCollection(dbus.service.Object):
|
||||
session = objects.get(session_path, None)
|
||||
if not session or session.sender != sender:
|
||||
raise InvalidArgs("session invalid: %s" % session_path)
|
||||
if self.locked:
|
||||
raise IsLocked("collection is locked: %s" % self.path)
|
||||
|
||||
attributes = properties.get("org.freedesktop.Secret.Item.Attributes", { })
|
||||
label = properties.get("org.freedesktop.Secret.Item.Label", None)
|
||||
|
@ -224,6 +224,71 @@ test_store_async (Test *test,
|
||||
secret_password_free (password);
|
||||
}
|
||||
|
||||
static void
|
||||
test_store_unlock (Test *test,
|
||||
gconstpointer unused)
|
||||
{
|
||||
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
|
||||
GAsyncResult *result = NULL;
|
||||
SecretCollection *collection;
|
||||
SecretService *service;
|
||||
GError *error = NULL;
|
||||
gchar *password;
|
||||
gboolean ret;
|
||||
GList *objects;
|
||||
gint count;
|
||||
|
||||
service = secret_service_get_sync (SECRET_SERVICE_NONE, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* Check collection state */
|
||||
collection = secret_collection_new_for_dbus_path_sync (service, collection_path,
|
||||
SECRET_COLLECTION_NONE, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (secret_collection_get_locked (collection) == FALSE);
|
||||
|
||||
/* Lock it, use async, so collection properties update */
|
||||
objects = g_list_append (NULL, collection);
|
||||
secret_service_lock (service, objects, NULL, on_complete_get_result, &result);
|
||||
egg_test_wait ();
|
||||
count = secret_service_lock_finish (service, result, NULL, &error);
|
||||
g_assert_cmpint (count, ==, 1);
|
||||
g_clear_object (&result);
|
||||
g_list_free (objects);
|
||||
|
||||
/* Check collection state */
|
||||
g_assert (secret_collection_get_locked (collection) == TRUE);
|
||||
|
||||
/* Store the password, use async so collection properties update */
|
||||
secret_password_store (&MOCK_SCHEMA, collection_path, "Label here",
|
||||
"the password", NULL, on_complete_get_result, &result,
|
||||
"even", TRUE,
|
||||
"string", "twelve",
|
||||
"number", 12,
|
||||
NULL);
|
||||
g_assert (result == NULL);
|
||||
egg_test_wait ();
|
||||
ret = secret_password_store_finish (result, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret == TRUE);
|
||||
g_clear_object (&result);
|
||||
|
||||
/* Check collection state */
|
||||
g_assert (secret_collection_get_locked (collection) == FALSE);
|
||||
|
||||
|
||||
password = secret_password_lookup_nonpageable_sync (&MOCK_SCHEMA, NULL, &error,
|
||||
"string", "twelve",
|
||||
NULL);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpstr (password, ==, "the password");
|
||||
|
||||
secret_password_free (password);
|
||||
g_object_unref (collection);
|
||||
g_object_unref (service);
|
||||
}
|
||||
|
||||
static void
|
||||
test_delete_sync (Test *test,
|
||||
gconstpointer used)
|
||||
@ -320,6 +385,7 @@ main (int argc, char **argv)
|
||||
|
||||
g_test_add ("/password/store-sync", Test, "mock-service-normal.py", setup, test_store_sync, teardown);
|
||||
g_test_add ("/password/store-async", Test, "mock-service-normal.py", setup, test_store_async, teardown);
|
||||
g_test_add ("/password/store-unlock", Test, "mock-service-normal.py", setup, test_store_unlock, teardown);
|
||||
|
||||
g_test_add ("/password/delete-sync", Test, "mock-service-delete.py", setup, test_delete_sync, teardown);
|
||||
g_test_add ("/password/delete-async", Test, "mock-service-delete.py", setup, test_delete_async, teardown);
|
||||
|
Loading…
Reference in New Issue
Block a user