[epiphany/wip/dueno/libsecret-simple] password-manager: Port to the secret_password* API



commit ed514f3ef43b323c51fb539274bef9dce0907ff2
Author: Daiki Ueno <dueno src gnome org>
Date:   Sat Jun 29 08:03:00 2019 +0200

    password-manager: Port to the secret_password* API
    
    This switches from using the D-Bus based libsecret API to the simple
    API that doesn't impose the particular backend implementation.  That
    would make it easier to migrate to the local storage in the future.

 lib/sync/ephy-password-manager.c | 186 ++++++++++++++++++++++++---------------
 meson.build                      |   2 +-
 2 files changed, 116 insertions(+), 72 deletions(-)
---
diff --git a/lib/sync/ephy-password-manager.c b/lib/sync/ephy-password-manager.c
index a27cdbafe..fd5512a78 100644
--- a/lib/sync/ephy-password-manager.c
+++ b/lib/sync/ephy-password-manager.c
@@ -64,6 +64,8 @@ G_DEFINE_TYPE_WITH_CODE (EphyPasswordManager, ephy_password_manager, G_TYPE_OBJE
 typedef struct {
   EphyPasswordManagerQueryCallback callback;
   gpointer user_data;
+  GList *records;
+  guint n_matches;
 } QueryAsyncData;
 
 typedef struct {
@@ -351,9 +353,9 @@ ephy_password_manager_get_usernames_for_origin (EphyPasswordManager *self,
 }
 
 static void
-secret_service_store_cb (SecretService         *service,
-                         GAsyncResult          *result,
-                         ManageRecordAsyncData *data)
+secret_password_store_cb (GObject               *source_object,
+                          GAsyncResult          *result,
+                          ManageRecordAsyncData *data)
 {
   GError *error = NULL;
   const char *origin;
@@ -362,7 +364,7 @@ secret_service_store_cb (SecretService         *service,
   origin = ephy_password_record_get_origin (data->record);
   username = ephy_password_record_get_username (data->record);
 
-  secret_service_store_finish (service, result, &error);
+  secret_password_store_finish (result, &error);
   if (error) {
     g_warning ("Failed to store password record for (%s, %s, %s, %s, %s): %s",
                origin,
@@ -384,7 +386,6 @@ ephy_password_manager_store_record (EphyPasswordManager *self,
                                     EphyPasswordRecord  *record)
 {
   GHashTable *attributes;
-  SecretValue *value;
   const char *origin;
   const char *target_origin;
   const char *username;
@@ -424,14 +425,12 @@ ephy_password_manager_store_record (EphyPasswordManager *self,
                                      username_field, password_field,
                                      modified);
 
-  value = secret_value_new (password, -1, "text/plain");
-  secret_service_store (NULL, EPHY_FORM_PASSWORD_SCHEMA,
-                        attributes, NULL, label, value, NULL,
-                        (GAsyncReadyCallback)secret_service_store_cb,
-                        manage_record_async_data_new (self, record));
+  secret_password_storev (EPHY_FORM_PASSWORD_SCHEMA,
+                          attributes, NULL, label, password, NULL,
+                          (GAsyncReadyCallback)secret_password_store_cb,
+                          manage_record_async_data_new (self, record));
 
   g_free (label);
-  secret_value_unref (value);
   g_hash_table_unref (attributes);
 }
 
@@ -511,63 +510,109 @@ ephy_password_manager_save (EphyPasswordManager *self,
 }
 
 static void
-secret_service_search_cb (SecretService  *service,
-                          GAsyncResult   *result,
-                          QueryAsyncData *data)
+retrieve_secret_cb (GObject        *source_object,
+                    GAsyncResult   *result,
+                    QueryAsyncData *data)
 {
-  GList *matches = NULL;
-  GList *records = NULL;
+  SecretRetrievable *retrievable = SECRET_RETRIEVABLE (source_object);
+  GHashTable *attributes = NULL;
+  const char *id;
+  const char *origin;
+  const char *target_origin;
+  const char *username;
+  const char *username_field;
+  const char *password_field;
+  const char *timestamp;
+  gint64 created;
+  gint64 modified;
+  const char *password;
+  gint64 server_time_modified;
+  EphyPasswordRecord *record;
+  SecretValue *value = NULL;
   GError *error = NULL;
 
-  matches = secret_service_search_finish (service, result, &error);
-  if (error) {
-    g_warning ("Failed to search secrets in password schema: %s", error->message);
+  value = secret_retrievable_retrieve_secret_finish (retrievable, result, &error);
+  if (!value) {
+    g_warning ("Failed to retrieve password: %s", error->message);
     g_error_free (error);
     goto out;
   }
 
-  for (GList *l = matches; l && l->data; l = l->next) {
-    SecretItem *item = (SecretItem *)l->data;
-    GHashTable *attributes = secret_item_get_attributes (item);
-    SecretValue *value = secret_item_get_secret (item);
-    const char *id = g_hash_table_lookup (attributes, ID_KEY);
-    const char *origin = g_hash_table_lookup (attributes, ORIGIN_KEY);
-    const char *target_origin = g_hash_table_lookup (attributes, TARGET_ORIGIN_KEY);
-    const char *username = g_hash_table_lookup (attributes, USERNAME_KEY);
-    const char *username_field = g_hash_table_lookup (attributes, USERNAME_FIELD_KEY);
-    const char *password_field = g_hash_table_lookup (attributes, PASSWORD_FIELD_KEY);
-    const char *timestamp = g_hash_table_lookup (attributes, SERVER_TIME_MODIFIED_KEY);
-    const char *password = secret_value_get (value, NULL);
-    gint64 server_time_modified;
-    EphyPasswordRecord *record;
-
-    LOG ("Found password record for (%s, %s, %s, %s, %s)",
-         origin, target_origin, username, username_field, password_field);
+  attributes = secret_retrievable_get_attributes (retrievable);
+  id = g_hash_table_lookup (attributes, ID_KEY);
+  origin = g_hash_table_lookup (attributes, ORIGIN_KEY);
+  target_origin = g_hash_table_lookup (attributes, TARGET_ORIGIN_KEY);
+  username = g_hash_table_lookup (attributes, USERNAME_KEY);
+  username_field = g_hash_table_lookup (attributes, USERNAME_FIELD_KEY);
+  password_field = g_hash_table_lookup (attributes, PASSWORD_FIELD_KEY);
+  timestamp = g_hash_table_lookup (attributes, SERVER_TIME_MODIFIED_KEY);
+  created = secret_retrievable_get_created (retrievable);
+  modified = secret_retrievable_get_modified (retrievable);
+
+  LOG ("Found password record for (%s, %s, %s, %s, %s)",
+       origin, target_origin, username, username_field, password_field);
 
-    if (!id || !origin || !target_origin || !timestamp) {
-      LOG ("Password record is corrupted, skipping it...");
-      goto next;
-    }
+  if (!id || !origin || !target_origin || !timestamp) {
+    LOG ("Password record is corrupted, skipping it...");
+    goto out;
+  }
+
+  password = secret_value_get_text (value);
+
+  record = ephy_password_record_new (id, origin, target_origin,
+                                     username, password,
+                                     username_field, password_field,
+                                     created * 1000,
+                                     modified * 1000);
+  server_time_modified = g_ascii_strtod (timestamp, NULL);
+  ephy_synchronizable_set_server_time_modified (EPHY_SYNCHRONIZABLE (record),
+                                                server_time_modified);
+  data->records = g_list_prepend (data->records, record);
 
-    record = ephy_password_record_new (id, origin, target_origin,
-                                       username, password,
-                                       username_field, password_field,
-                                       secret_item_get_created (item) * 1000,
-                                       secret_item_get_modified (item) * 1000);
-    server_time_modified = g_ascii_strtod (timestamp, NULL);
-    ephy_synchronizable_set_server_time_modified (EPHY_SYNCHRONIZABLE (record),
-                                                  server_time_modified);
-    records = g_list_prepend (records, record);
-
-next:
+out:
+  if (value)
     secret_value_unref (value);
+  if (attributes)
     g_hash_table_unref (attributes);
+  g_object_unref (retrievable);
+
+  if (--data->n_matches == 0) {
+    if (data->callback)
+      data->callback (data->records, data->user_data);
+    query_async_data_free (data);
+  }
+}
+
+static void
+secret_password_search_cb (GObject        *source_object,
+                           GAsyncResult   *result,
+                           QueryAsyncData *data)
+{
+  GList *matches;
+  GError *error = NULL;
+
+  matches = secret_password_search_finish (result, &error);
+  if (!matches) {
+    if (error) {
+      g_warning ("Failed to search secrets in password schema: %s", error->message);
+      g_error_free (error);
+    }
+    if (data->callback)
+      data->callback (NULL, data->user_data);
+    return;
+  }
+
+  data->records = NULL;
+  data->n_matches = g_list_length (matches);
+
+  for (GList *l = matches; l; l = l->next) {
+    SecretRetrievable *retrievable = SECRET_RETRIEVABLE (l->data);
+    secret_retrievable_retrieve_secret (g_object_ref (retrievable),
+                                        NULL,
+                                        (GAsyncReadyCallback)retrieve_secret_cb,
+                                        data);
   }
 
-out:
-  if (data->callback)
-    data->callback (records, data->user_data);
-  query_async_data_free (data);
   g_list_free_full (matches, g_object_unref);
 }
 
@@ -594,25 +639,24 @@ ephy_password_manager_query (EphyPasswordManager              *self,
                                      username_field, password_field, -1);
   data = query_async_data_new (callback, user_data);
 
-  secret_service_search (NULL,
-                         EPHY_FORM_PASSWORD_SCHEMA,
-                         attributes,
-                         SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
-                         NULL,
-                         (GAsyncReadyCallback)secret_service_search_cb,
-                         data);
+  secret_password_searchv (EPHY_FORM_PASSWORD_SCHEMA,
+                           attributes,
+                           SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
+                           NULL,
+                           (GAsyncReadyCallback)secret_password_search_cb,
+                           data);
 
   g_hash_table_unref (attributes);
 }
 
 static void
-secret_service_clear_cb (SecretService *service,
-                         GAsyncResult  *result,
-                         gpointer       user_data)
+secret_password_clear_cb (GObject      *source_object,
+                          GAsyncResult *result,
+                          gpointer      user_data)
 {
   GError *error = NULL;
 
-  secret_service_clear_finish (service, result, &error);
+  secret_password_clear_finish (result, &error);
   if (error) {
     g_warning ("Failed to clear secrets from password schema: %s", error->message);
     g_error_free (error);
@@ -651,9 +695,9 @@ ephy_password_manager_forget_record (EphyPasswordManager *self,
        ephy_password_record_get_username_field (record),
        ephy_password_record_get_password_field (record));
 
-  secret_service_clear (NULL, EPHY_FORM_PASSWORD_SCHEMA, attributes, NULL,
-                        (GAsyncReadyCallback)secret_service_clear_cb,
-                        replacement ? manage_record_async_data_new (self, replacement) : NULL);
+  secret_password_clearv (EPHY_FORM_PASSWORD_SCHEMA, attributes, NULL,
+                          (GAsyncReadyCallback)secret_password_clear_cb,
+                          replacement ? manage_record_async_data_new (self, replacement) : NULL);
 
   ephy_password_manager_cache_remove (self,
                                       ephy_password_record_get_origin (record),
@@ -703,8 +747,8 @@ forget_all_cb (GList    *records,
   GHashTable *attributes;
 
   attributes = secret_attributes_build (EPHY_FORM_PASSWORD_SCHEMA, NULL);
-  secret_service_clear (NULL, EPHY_FORM_PASSWORD_SCHEMA, attributes, NULL,
-                        (GAsyncReadyCallback)secret_service_clear_cb, NULL);
+  secret_password_clearv (EPHY_FORM_PASSWORD_SCHEMA, attributes, NULL,
+                          (GAsyncReadyCallback)secret_password_clear_cb, NULL);
 
   for (GList *l = records; l && l->data; l = l->next)
     g_signal_emit_by_name (self, "synchronizable-deleted", l->data);
diff --git a/meson.build b/meson.build
index f07f6de65..08e9787b4 100644
--- a/meson.build
+++ b/meson.build
@@ -94,7 +94,7 @@ json_glib_dep = dependency('json-glib-1.0', version: '>= 1.2.4')
 libdazzle_dep = dependency('libdazzle-1.0', version: '>= 3.31.90')
 libhandy_dep = dependency('libhandy-0.0', version: '>= 0.0.10', required: false)
 libnotify_dep = dependency('libnotify', version: '>= 0.5.1')
-libsecret_dep = dependency('libsecret-1', version: '>= 0.14')
+libsecret_dep = dependency('libsecret-1', version: '>= 0.19.0')
 libsoup_dep = dependency('libsoup-2.4', version: '>= 2.48.0')
 libxml_dep = dependency('libxml-2.0', version: '>= 2.6.12')
 nettle_dep = dependency('nettle', version: nettle_requirement)


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