summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2022-05-27 11:12:32 +0200
committerNiels De Graef <nielsdegraef@gmail.com>2022-09-24 07:25:52 +0000
commit8d588a700f1c8461324a6fb4987f9fc450534857 (patch)
treed9a447e2f59cf11f1ff4e7065a68e806b96cbdc7
parent921f5f0d2eda9f87c6a6af234d068addb5d749f1 (diff)
downloadlibsecret-nielsdg/less-secret-sync.tar.gz
Replace some SecretSync with a sync implementationnielsdg/less-secret-sync
The idea behind `SecretSync` is a nice thing: it allows use to re-use our async implementations of methods for the synchronous versions. The big problem with it, is that it makes debugging issues much harder (especially with issues related to freezes) since things can seem to be stuck in `poll()` somewhere. Even though it adds quite a bit of code, I think it makes sense to replace some instances with a proper synchronous implementation. Note that we don't do this for all usages of `SecretSync` though, as some things will need some kind of main loop interaction anyway (for example, when waiting for a portal's Response signal) Another nice advantage is that it's easier to follow the logic in the sync code than the async version.
-rw-r--r--libsecret/secret-collection.c23
-rw-r--r--libsecret/secret-paths.c122
-rw-r--r--libsecret/secret-private.h6
3 files changed, 112 insertions, 39 deletions
diff --git a/libsecret/secret-collection.c b/libsecret/secret-collection.c
index 635e173..6039ffe 100644
--- a/libsecret/secret-collection.c
+++ b/libsecret/secret-collection.c
@@ -1705,26 +1705,19 @@ secret_collection_delete_sync (SecretCollection *self,
GCancellable *cancellable,
GError **error)
{
- SecretSync *sync;
- gboolean ret;
+ const char *object_path;
g_return_val_if_fail (SECRET_IS_COLLECTION (self), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- sync = _secret_sync_new ();
- g_main_context_push_thread_default (sync->context);
-
- secret_collection_delete (self, cancellable, _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- ret = secret_collection_delete_finish (self, sync->result, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return ret;
+ object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
+ if (!_secret_service_delete_path_sync (self->pv->service, object_path, FALSE,
+ cancellable, error)) {
+ _secret_util_strip_remote_error (error);
+ return FALSE;
+ }
+ return TRUE;
}
/**
diff --git a/libsecret/secret-paths.c b/libsecret/secret-paths.c
index 8081819..e5114cb 100644
--- a/libsecret/secret-paths.c
+++ b/libsecret/secret-paths.c
@@ -431,28 +431,37 @@ secret_collection_search_for_dbus_paths_sync (SecretCollection *collection,
GCancellable *cancellable,
GError **error)
{
- SecretSync *sync;
- gchar **paths;
+ const char *schema_name = NULL;
+ GVariant *response = NULL;
+ char **paths = NULL;
g_return_val_if_fail (SECRET_IS_COLLECTION (collection), NULL);
g_return_val_if_fail (attributes != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- sync = _secret_sync_new ();
- g_main_context_push_thread_default (sync->context);
+ /* Warnings raised already */
+ if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
+ return NULL;
- secret_collection_search_for_dbus_paths (collection, schema, attributes, cancellable,
- _secret_sync_on_result, sync);
+ if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
+ schema_name = schema->name;
- g_main_loop_run (sync->loop);
- paths = secret_collection_search_for_dbus_paths_finish (collection, sync->result, error);
+ response =
+ g_dbus_proxy_call_sync (G_DBUS_PROXY (collection), "SearchItems",
+ g_variant_new ("(@a{ss})",
+ _secret_attributes_to_variant (attributes, schema_name)),
+ G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
+ if (response == NULL) {
+ _secret_util_strip_remote_error (error);
+ return FALSE;
+ }
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
+ g_variant_get (response, "(^ao)", &paths);
+ g_variant_unref (response);
- return paths;
+ return g_steal_pointer (&paths);
}
/**
@@ -827,28 +836,37 @@ secret_service_get_secret_for_dbus_path_sync (SecretService *self,
GCancellable *cancellable,
GError **error)
{
- SecretSync *sync;
- SecretValue *value;
+ const char *session = NULL;
+ GVariant *response = NULL;
+ SecretValue *ret = NULL;
g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
g_return_val_if_fail (item_path != NULL, NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- sync = _secret_sync_new ();
- g_main_context_push_thread_default (sync->context);
-
- secret_service_get_secret_for_dbus_path (self, item_path, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
+ if (!secret_service_ensure_session_sync (self, cancellable, error)) {
+ _secret_util_strip_remote_error (error);
+ return NULL;
+ }
- value = secret_service_get_secret_for_dbus_path_finish (self, sync->result, error);
+ session = secret_service_get_session_dbus_path (self);
+ response =
+ g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "GetSecrets",
+ g_variant_new ("(@aoo)",
+ g_variant_new_objv (&item_path, 1),
+ session),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
+ cancellable, error);
+ if (response) {
+ ret = _secret_service_decode_get_secrets_first (self, response);
+ } else {
+ _secret_util_strip_remote_error (error);
+ }
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
+ g_clear_pointer (&response, g_variant_unref);
- return value;
+ return ret;
}
/**
@@ -1519,6 +1537,62 @@ _secret_service_delete_path_finish (SecretService *self,
return TRUE;
}
+gboolean
+_secret_service_delete_path_sync (SecretService *self,
+ const char *object_path,
+ gboolean is_an_item,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *err = NULL;
+ GVariant *prompt_variant = NULL;
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
+ g_return_val_if_fail (object_path != NULL, FALSE);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+
+ prompt_variant =
+ g_dbus_connection_call_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (self)),
+ g_dbus_proxy_get_name (G_DBUS_PROXY (self)),
+ object_path,
+ is_an_item ? SECRET_ITEM_INTERFACE : SECRET_COLLECTION_INTERFACE,
+ "Delete", g_variant_new ("()"), G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
+ cancellable,
+ &err);
+ if (err == NULL) {
+ const char *prompt_path;
+
+ g_variant_get (prompt_variant, "(&o)", &prompt_path);
+
+ /* show a prompt if needed */
+ if (!_secret_util_empty_path (prompt_path)) {
+ SecretPrompt *prompt = NULL;
+ GVariant *prompt_result = NULL;
+
+ prompt = _secret_prompt_instance (self, prompt_path);
+ prompt_result = secret_service_prompt_sync (self,
+ prompt,
+ cancellable,
+ NULL,
+ &err);
+ ret = (err != NULL);
+ g_clear_pointer (&prompt_result, g_variant_unref);
+ }
+
+ } else {
+ ret = FALSE;
+ }
+
+ g_clear_pointer (&prompt_variant, g_variant_unref);
+ if (err) {
+ _secret_util_strip_remote_error (&err);
+ g_propagate_error (error, err);
+ }
+ return ret;
+}
+
/**
* secret_service_delete_item_dbus_path: (skip)
* @self: the secret service
diff --git a/libsecret/secret-private.h b/libsecret/secret-private.h
index 87633f6..81bad9a 100644
--- a/libsecret/secret-private.h
+++ b/libsecret/secret-private.h
@@ -140,6 +140,12 @@ gboolean _secret_service_delete_path_finish (SecretService *se
GAsyncResult *result,
GError **error);
+gboolean _secret_service_delete_path_sync (SecretService *self,
+ const char *object_path,
+ gboolean is_an_item,
+ GCancellable *cancellable,
+ GError **error);
+
void _secret_service_search_for_paths_variant (SecretService *self,
GVariant *attributes,
GCancellable *cancellable,