[libsecret] secret_service_remove() and secret_password_remove() remove multiple



commit 8583ef53dc51015a3c38e38a2538438a6589f58e
Author: Stef Walter <stefw gnome org>
Date:   Tue Jul 10 21:38:48 2012 +0200

    secret_service_remove() and secret_password_remove() remove multiple
    
     * Remove all items that are not locked that match in a
       secret_service_remove() and secret_password_remove().

 library/secret-methods.c      |   58 +++++++++++++++++++----------------------
 library/secret-password.c     |   16 +++++-----
 library/tests/test-methods.c  |    8 +++++-
 library/tests/test-password.c |   10 +++++++
 4 files changed, 52 insertions(+), 40 deletions(-)
---
diff --git a/library/secret-methods.c b/library/secret-methods.c
index 75af012..3393408 100644
--- a/library/secret-methods.c
+++ b/library/secret-methods.c
@@ -1487,8 +1487,8 @@ typedef struct {
 	GCancellable *cancellable;
 	SecretService *service;
 	GVariant *attributes;
-	SecretPrompt *prompt;
-	gboolean deleted;
+	gint deleted;
+	gint deleting;
 } DeleteClosure;
 
 static void
@@ -1498,7 +1498,6 @@ delete_closure_free (gpointer data)
 	if (closure->service)
 		g_object_unref (closure->service);
 	g_variant_unref (closure->attributes);
-	g_clear_object (&closure->prompt);
 	g_clear_object (&closure->cancellable);
 	g_slice_free (DeleteClosure, closure);
 }
@@ -1511,12 +1510,18 @@ on_delete_password_complete (GObject *source,
 	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
 	DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
 	GError *error = NULL;
+	gboolean deleted;
 
-	closure->deleted = _secret_service_delete_path_finish (SECRET_SERVICE (source), result, &error);
+	closure->deleting--;
+
+	deleted = _secret_service_delete_path_finish (SECRET_SERVICE (source), result, &error);
 	if (error != NULL)
 		g_simple_async_result_take_error (res, error);
+	if (deleted)
+		closure->deleted++;
 
-	g_simple_async_result_complete (res);
+	if (closure->deleting <= 0)
+		g_simple_async_result_complete (res);
 
 	g_object_unref (res);
 }
@@ -1528,39 +1533,27 @@ on_delete_searched (GObject *source,
 {
 	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
 	DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
-	const gchar *path = NULL;
 	GError *error = NULL;
-	gchar **locked;
-	gchar **unlocked;
-
-	secret_service_search_for_dbus_paths_finish (SECRET_SERVICE (source), result, &unlocked, &locked, &error);
-	if (error != NULL) {
-		g_simple_async_result_take_error (res, error);
-		g_simple_async_result_complete (res);
-
-	} else {
-		/* Choose the first path */
-		if (unlocked && unlocked[0])
-			path = unlocked[0];
-		else if (locked && locked[0])
-			path = locked[0];
-
-		/* Nothing to delete? */
-		if (path == NULL) {
-			closure->deleted = FALSE;
-			g_simple_async_result_complete (res);
+	gchar **unlocked = NULL;
+	gint i;
 
-		/* Delete the first path */
-		} else {
-			closure->deleted = TRUE;
-			_secret_service_delete_path (closure->service, path, TRUE,
+	secret_service_search_for_dbus_paths_finish (SECRET_SERVICE (source), result, &unlocked, NULL, &error);
+	if (error == NULL) {
+		for (i = 0; unlocked[i] != NULL; i++) {
+			_secret_service_delete_path (closure->service, unlocked[i], TRUE,
 			                             closure->cancellable,
 			                             on_delete_password_complete,
 			                             g_object_ref (res));
+			closure->deleting++;
 		}
+
+		if (closure->deleting == 0)
+			g_simple_async_result_complete (res);
+	} else {
+		g_simple_async_result_take_error (res, error);
+		g_simple_async_result_complete (res);
 	}
 
-	g_strfreev (locked);
 	g_strfreev (unlocked);
 	g_object_unref (res);
 }
@@ -1639,6 +1632,9 @@ secret_service_remove (SecretService *service,
 	g_variant_ref_sink (closure->attributes);
 	g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
 
+	/* A double check to make sure we don't delete everything, should have been checked earlier */
+	g_assert (g_variant_n_children (closure->attributes) > 0);
+
 	if (service == NULL) {
 		secret_service_get (SECRET_SERVICE_NONE, cancellable,
 		                    on_delete_service, g_object_ref (res));
@@ -1681,7 +1677,7 @@ secret_service_remove_finish (SecretService *service,
 		return FALSE;
 
 	closure = g_simple_async_result_get_op_res_gpointer (res);
-	return closure->deleted;
+	return closure->deleted > 0;
 }
 
 /**
diff --git a/library/secret-password.c b/library/secret-password.c
index 78a2157..f506596 100644
--- a/library/secret-password.c
+++ b/library/secret-password.c
@@ -684,7 +684,7 @@ secret_password_remove (const SecretSchema *schema,
  *
  * The @attributes should be a set of key and value string pairs.
  *
- * If multiple items match the attributes, then only one will be deleted.
+ * All unlocked items that match the attributes will be deleted.
  *
  * This method will return immediately and complete asynchronously.
  *
@@ -714,10 +714,10 @@ secret_password_removev (const SecretSchema *schema,
  * @result: the asynchronous result passed to the callback
  * @error: location to place an error on failure
  *
- * Finish an asynchronous operation to remove a password from the secret
+ * Finish an asynchronous operation to remove passwords from the secret
  * service.
  *
- * Returns: whether the removal was successful or not
+ * Returns: whether any passwords were removed
  */
 gboolean
 secret_password_remove_finish (GAsyncResult *result,
@@ -734,19 +734,19 @@ secret_password_remove_finish (GAsyncResult *result,
  * @error: location to place an error on failure
  * @...: the attribute keys and values, terminated with %NULL
  *
- * Remove a password from the secret service.
+ * Remove passwords from the secret service.
  *
  * The variable argument list should contain pairs of a) The attribute name as
  * a null-terminated string, followed by b) attribute value, either a character
  * string, an int number, or a gboolean value, as defined in the password
  * @schema. The list of attribtues should be terminated with a %NULL.
  *
- * If multiple items match the attributes, then only one will be deleted.
+ * All unlocked items that match the attributes will be deleted.
  *
  * This method may block indefinitely and should not be used in user interface
  * threads.
  *
- * Returns: whether the removal was successful or not
+ * Returns: whether the any passwords were removed
  */
 gboolean
 secret_password_remove_sync (const SecretSchema* schema,
@@ -785,12 +785,12 @@ secret_password_remove_sync (const SecretSchema* schema,
  *
  * The @attributes should be a set of key and value string pairs.
  *
- * If multiple items match the attributes, then only one will be deleted.
+ * All unlocked items that match the attributes will be deleted.
  *
  * This method may block indefinitely and should not be used in user interface
  * threads.
  *
- * Returns: whether the removal was successful or not
+ * Returns: whether any passwords were removed
  *
  * Rename to: secret_password_remove_sync
  */
diff --git a/library/tests/test-methods.c b/library/tests/test-methods.c
index 9dc8214..8b77dbc 100644
--- a/library/tests/test-methods.c
+++ b/library/tests/test-methods.c
@@ -513,11 +513,12 @@ test_remove_locked (Test *test,
 	                                      "number", 3,
 	                                      NULL);
 
+	/* Locked items can't be removed via this API */
 	ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error);
 
 	g_hash_table_unref (attributes);
 	g_assert_no_error (error);
-	g_assert (ret == TRUE);
+	g_assert (ret == FALSE);
 }
 
 static void
@@ -545,6 +546,7 @@ static void
 test_remove_no_name (Test *test,
                      gconstpointer used)
 {
+	const gchar *paths[] = { "/org/freedesktop/secrets/collection/german", NULL };
 	GError *error = NULL;
 	GHashTable *attributes;
 	gboolean ret;
@@ -558,6 +560,10 @@ test_remove_no_name (Test *test,
 	g_assert_no_error (error);
 	g_assert (ret == FALSE);
 
+	/* We need this collection unlocked for the next test */
+	secret_service_unlock_dbus_paths_sync (test->service, paths, NULL, NULL, &error);
+	g_assert_no_error (error);
+
 	/* We have an item with 5 in prime schema, but should match anyway becase of flags */
 	ret = secret_service_remove_sync (test->service, &NO_NAME_SCHEMA, attributes, NULL, &error);
 	g_assert_no_error (error);
diff --git a/library/tests/test-password.c b/library/tests/test-password.c
index d5829df..303fae7 100644
--- a/library/tests/test-password.c
+++ b/library/tests/test-password.c
@@ -15,6 +15,7 @@
 #include "config.h"
 
 #include "secret-password.h"
+#include "secret-paths.h"
 #include "secret-private.h"
 
 #include "mock-service.h"
@@ -269,6 +270,8 @@ static void
 test_remove_no_name (Test *test,
                      gconstpointer used)
 {
+	const gchar *paths[] = { "/org/freedesktop/secrets/collection/german", NULL };
+	SecretService *service;
 	GError *error = NULL;
 	gboolean ret;
 
@@ -279,6 +282,13 @@ test_remove_no_name (Test *test,
 	g_assert_no_error (error);
 	g_assert (ret == FALSE);
 
+	/* We need this collection unlocked for the next test */
+	service = secret_service_get_sync (SECRET_SERVICE_NONE, NULL, &error);
+	g_assert_no_error (error);
+	secret_service_unlock_dbus_paths_sync (service, paths, NULL, NULL, &error);
+	g_assert_no_error (error);
+	g_object_unref (service);
+
 	/* We have an item with 5 in prime schema, but should match anyway becase of flags */
 	ret = secret_password_remove_sync (&NO_NAME_SCHEMA, NULL, &error,
 	                                  "number", 5,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]