[libsecret] Register secret service errors as DBus errors



commit 30d1337a7cb60693fbcee5ce67cc3907d144d35a
Author: Stef Walter <stefw gnome org>
Date:   Mon Jul 9 08:44:50 2012 +0200

    Register secret service errors as DBus errors
    
     * and strip remote error codes from error->message so that
       they don't clutter things.

 library/secret-item.c       |   14 +++++++++---
 library/secret-paths.c      |   12 +++++++++-
 library/secret-private.h    |    2 +
 library/secret-prompt.c     |    2 +
 library/secret-service.c    |    4 +++
 library/secret-session.c    |    2 +
 library/secret-types.h      |    3 ++
 library/secret-util.c       |   48 ++++++++++++++++++++++++++++++++++--------
 library/tests/test-prompt.c |   11 +++++++++
 9 files changed, 84 insertions(+), 14 deletions(-)
---
diff --git a/library/secret-item.c b/library/secret-item.c
index cba4308..c8076fa 100644
--- a/library/secret-item.c
+++ b/library/secret-item.c
@@ -1137,8 +1137,10 @@ on_item_load_secret (GObject *source,
 		}
 	}
 
-	if (error != NULL)
+	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
+	}
 
 	g_simple_async_result_complete (res);
 	g_object_unref (res);
@@ -1337,8 +1339,10 @@ on_get_secrets_complete (GObject *source,
 		g_variant_unref (retval);
 	}
 
-	if (error != NULL)
+	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (async, error);
+	}
 
 	g_simple_async_result_complete (async);
 	g_object_unref (async);
@@ -1545,10 +1549,12 @@ on_item_set_secret (GObject *source,
 
 	retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
 
-	if (error == NULL)
+	if (error == NULL) {
 		_secret_item_set_cached_secret (self, set->value);
-	else
+	} else {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
+	}
 	if (retval != NULL)
 		g_variant_unref (retval);
 
diff --git a/library/secret-paths.c b/library/secret-paths.c
index ab22daf..6b1fb34 100644
--- a/library/secret-paths.c
+++ b/library/secret-paths.c
@@ -539,8 +539,10 @@ on_get_secrets_complete (GObject *source,
 	GError *error = NULL;
 
 	closure->out = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
-	if (error != NULL)
+	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
+	}
 	g_simple_async_result_complete (res);
 
 	g_object_unref (res);
@@ -896,6 +898,7 @@ on_xlock_called (GObject *source,
 
 	retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
 	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		g_simple_async_result_complete (res);
 
@@ -1291,6 +1294,7 @@ on_delete_complete (GObject *source,
 		g_variant_unref (retval);
 
 	} else {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		g_simple_async_result_complete (res);
 	}
@@ -1519,6 +1523,7 @@ on_create_collection_called (GObject *source,
 		g_variant_unref (retval);
 
 	} else {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		g_simple_async_result_complete (res);
 	}
@@ -1784,6 +1789,7 @@ on_create_item_called (GObject *source,
 		g_variant_unref (retval);
 
 	} else {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		g_simple_async_result_complete (res);
 	}
@@ -2056,6 +2062,8 @@ secret_service_read_alias_dbus_path_finish (SecretService *self,
 	GVariant *retval;
 
 	retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (self), result, error);
+
+	_secret_util_strip_remote_error (error);
 	if (retval == NULL)
 		return NULL;
 
@@ -2174,6 +2182,8 @@ secret_service_set_alias_to_dbus_path_finish (SecretService *self,
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (self), result, error);
+
+	_secret_util_strip_remote_error (error);
 	if (retval == NULL)
 		return FALSE;
 
diff --git a/library/secret-private.h b/library/secret-private.h
index 66bb5d4..f5efa42 100644
--- a/library/secret-private.h
+++ b/library/secret-private.h
@@ -60,6 +60,8 @@ void                 _secret_sync_on_result                   (GObject *source,
 SecretPrompt *       _secret_prompt_instance                  (SecretService *service,
                                                                const gchar *prompt_path);
 
+void                 _secret_util_strip_remote_error          (GError **error);
+
 gchar *              _secret_util_parent_path                 (const gchar *path);
 
 gboolean             _secret_util_empty_path                  (const gchar *path);
diff --git a/library/secret-prompt.c b/library/secret-prompt.c
index 2d2ed01..6d8e2f8 100644
--- a/library/secret-prompt.c
+++ b/library/secret-prompt.c
@@ -331,6 +331,7 @@ on_prompt_prompted (GObject *source,
 		g_clear_error (&error);
 
 	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		perform_prompt_complete (res, TRUE);
 
@@ -377,6 +378,7 @@ on_prompt_dismissed (GObject *source,
 		g_clear_error (&error);
 
 	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		perform_prompt_complete (res, TRUE);
 	}
diff --git a/library/secret-service.c b/library/secret-service.c
index 658b04d..f58f2ff 100644
--- a/library/secret-service.c
+++ b/library/secret-service.c
@@ -103,6 +103,7 @@
 
 EGG_SECURE_GLIB_DEFINITIONS ();
 
+GQuark _secret_error_quark = 0;
 static const gchar *default_bus_name = SECRET_SERVICE_BUS_NAME;
 
 enum {
@@ -542,6 +543,9 @@ secret_service_class_init (SecretServiceClass *klass)
 	                                 _secret_list_get_type (), G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
 	g_type_class_add_private (klass, sizeof (SecretServicePrivate));
+
+	/* Initialize this error domain, registers dbus errors */
+	_secret_error_quark = secret_error_get_quark ();
 }
 
 typedef struct {
diff --git a/library/secret-session.c b/library/secret-session.c
index bfaa19f..b085bc5 100644
--- a/library/secret-session.c
+++ b/library/secret-session.c
@@ -248,6 +248,7 @@ on_service_open_session_plain (GObject *source,
 		g_variant_unref (response);
 
 	} else {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
 		g_simple_async_result_complete (res);
 	}
@@ -296,6 +297,7 @@ on_service_open_session_aes (GObject *source,
 
 		/* Other errors result in a failure */
 		} else {
+			_secret_util_strip_remote_error (&error);
 			g_simple_async_result_take_error (res, error);
 			g_simple_async_result_complete (res);
 		}
diff --git a/library/secret-types.h b/library/secret-types.h
index 70d1cf8..c0373ee 100644
--- a/library/secret-types.h
+++ b/library/secret-types.h
@@ -29,6 +29,9 @@ GQuark          secret_error_get_quark      (void) G_GNUC_CONST;
 
 typedef enum {
 	SECRET_ERROR_PROTOCOL = 1,
+	SECRET_ERROR_IS_LOCKED = 2,
+	SECRET_ERROR_NO_SUCH_OBJECT = 3,
+	SECRET_ERROR_ALREADY_EXISTS = 4,
 } SecretError;
 
 typedef struct _SecretCollection  SecretCollection;
diff --git a/library/secret-util.c b/library/secret-util.c
index ad4baeb..b91ad5a 100644
--- a/library/secret-util.c
+++ b/library/secret-util.c
@@ -35,6 +35,11 @@
  * SecretError:
  * @SECRET_ERROR_PROTOCOL: received an invalid data or message from the Secret
  *                         Service
+ * @SECRET_ERROR_IS_LOCKED: the item or collection is locked and the operation
+ *                          cannot be performed
+ * @SECRET_ERROR_NO_SUCH_OBJECT: no such item or collection found in the
+ *                               Secret Service
+ * @SECRET_ERROR_ALREADY_EXISTS: a relevant item or collection already exists
  *
  * Errors returned by the Secret Service. None of the errors are appropriate
  * for display to the user.
@@ -77,17 +82,38 @@ _secret_list_get_type (void)
 GQuark
 secret_error_get_quark (void)
 {
-	static volatile gsize initialized = 0;
-	static GQuark quark = 0;
+	static volatile gsize quark = 0;
 
-	if (g_once_init_enter (&initialized)) {
-		quark = g_quark_from_static_string ("secret-error");
-		g_once_init_leave (&initialized, 1);
-	}
+	static const GDBusErrorEntry entries[] = {
+		{ SECRET_ERROR_IS_LOCKED, "org.freedesktop.Secret.Error.IsLocked", },
+		{ SECRET_ERROR_NO_SUCH_OBJECT, "org.freedesktop.Secret.Error.NoSuchObject", },
+		{ SECRET_ERROR_ALREADY_EXISTS, "org.freedesktop.Secret.Error.AlreadyExists" },
+	};
+
+	g_dbus_error_register_error_domain ("secret-error", &quark,
+	                                    entries, G_N_ELEMENTS (entries));
 
 	return quark;
 }
 
+void
+_secret_util_strip_remote_error (GError **error)
+{
+	gchar *remote;
+
+	if (error == NULL || *error == NULL)
+		return;
+
+	remote = g_dbus_error_get_remote_error (*error);
+	if (remote) {
+		if (g_dbus_error_strip_remote_error (*error)) {
+			g_message ("Remote error from secret service: %s: %s",
+			           remote, (*error)->message);
+		}
+		g_free (remote);
+	}
+}
+
 gchar *
 _secret_util_parent_path (const gchar *path)
 {
@@ -177,10 +203,12 @@ on_get_properties (GObject *source,
 
 	retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
 
-	if (error == NULL)
+	if (error == NULL) {
 		process_get_all_reply (proxy, retval);
-	else
+	} else {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
+	}
 	if (retval != NULL)
 		g_variant_unref (retval);
 
@@ -262,8 +290,10 @@ on_set_property (GObject *source,
 
 	retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
 	                                        result, &error);
-	if (error != NULL)
+	if (error != NULL) {
+		_secret_util_strip_remote_error (&error);
 		g_simple_async_result_take_error (res, error);
+	}
 	if (retval != NULL)
 		g_variant_unref (retval);
 
diff --git a/library/tests/test-prompt.c b/library/tests/test-prompt.c
index 0bc03dd..7cd063e 100644
--- a/library/tests/test-prompt.c
+++ b/library/tests/test-prompt.c
@@ -378,6 +378,13 @@ test_service_path (Test *test,
 	egg_test_wait_idle ();
 }
 
+static void
+null_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
+                  const gchar *message, gpointer user_data)
+{
+
+}
+
 int
 main (int argc, char **argv)
 {
@@ -385,6 +392,10 @@ main (int argc, char **argv)
 	g_set_prgname ("test-prompt");
 	g_type_init ();
 
+	/* Suppress these messages in tests */
+	g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG,
+	                   null_log_handler, NULL);
+
 	g_test_add ("/prompt/run", Test, "mock-service-prompt.py", setup, test_perform_run, teardown);
 	g_test_add ("/prompt/perform-sync", Test, "mock-service-prompt.py", setup, test_perform_sync, teardown);
 	g_test_add ("/prompt/perform-async", Test, "mock-service-prompt.py", setup, test_perform_async, teardown);



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