[epiphany/wip/ephy-sync] Add functions for save/store, get/load, delete/forget tokens



commit 23a3416e0acb2016601043766d6e1395839cc488
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Fri Jun 24 18:13:42 2016 +0300

    Add functions for save/store, get/load, delete/forget tokens

 src/ephy-sync-secret.c  |  155 ++++++++++++++++++++---------------------------
 src/ephy-sync-secret.h  |   16 ++---
 src/ephy-sync-service.c |  110 ++++++++++++++++++++++------------
 src/ephy-sync-service.h |   39 +++++++-----
 src/ephy-sync-utils.c   |   17 +++++
 src/ephy-sync-utils.h   |   27 ++++++---
 6 files changed, 201 insertions(+), 163 deletions(-)
---
diff --git a/src/ephy-sync-secret.c b/src/ephy-sync-secret.c
index c1fb5ea..28e871b 100644
--- a/src/ephy-sync-secret.c
+++ b/src/ephy-sync-secret.c
@@ -27,8 +27,9 @@ ephy_sync_secret_get_token_schema (void)
   static const SecretSchema schema = {
     "org.epiphany.SyncToken", SECRET_SCHEMA_NONE,
     {
-      { EMAIL_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
-      { TOKEN_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { EMAIL_KEY,      SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { TOKEN_TYPE_KEY, SECRET_SCHEMA_ATTRIBUTE_INTEGER },
+      { TOKEN_NAME_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
       { "NULL", 0 },
     }
   };
@@ -38,148 +39,123 @@ ephy_sync_secret_get_token_schema (void)
 static void
 forget_all_tokens_cb (SecretService *service,
                       GAsyncResult  *result,
-                      GTask         *task)
+                      gpointer       user_data)
 {
   GError *error = NULL;
 
   secret_service_clear_finish (service, result, &error);
 
-  if (error != NULL) {
-LOG ("%s:%d", __func__, __LINE__);
-    g_task_return_error (task, error);
-  }
-  else {
-LOG ("%s:%d", __func__, __LINE__);
-    g_task_return_boolean (task, TRUE);
-  }
-
-  g_object_unref (task);
-}
-
-static void
-load_tokens_cb (SecretService *service,
-                GAsyncResult  *result,
-                gpointer       user_data)
-{
-  EphySyncService *sync_service;
-  GHashTable *attributes;
-  SecretItem *secret_item;
-  SecretValue *secret_value;
-  GList *matches;
-  GList *tmp;
-  const gchar *emailUTF8;
-  const gchar *token_name;
-  const gchar *token_value_hex;
-
-  sync_service = EPHY_SYNC_SERVICE (user_data);
-  matches = secret_service_search_finish (service, result, NULL);
-
-  for (tmp = matches; tmp != NULL; tmp = tmp->next) {
-    secret_item = tmp->data;
-
-    attributes = secret_item_get_attributes (secret_item);
-    emailUTF8 = g_hash_table_lookup (attributes, EMAIL_KEY);
-    token_name = g_hash_table_lookup (attributes, TOKEN_KEY);
-    secret_value = secret_item_get_secret (secret_item);
-    token_value_hex = secret_value_get_text (secret_value);
-
-    if (g_strcmp0 (emailUTF8, sync_service->user_email) == 0) {
-      ephy_sync_service_set_token (sync_service, token_name, token_value_hex);
-LOG ("[%d] Set token %s with value %s for email: %s", __LINE__, token_name, token_value_hex, emailUTF8);
-    }
-
-    g_hash_table_unref (attributes);
-  }
-
-LOG ("%s:%d", __func__, __LINE__);
-  g_list_free_full (matches, g_object_unref);
+  if (error)
+LOG ("[%d] Error clearing token secret schema: %s", __LINE__, error->message);
+  else
+LOG ("[%d] Successfully cleared token secret schema", __LINE__);
 }
 
 static void
 store_token_cb (SecretService *service,
                 GAsyncResult  *result,
-                GTask         *task)
+                gpointer       user_data)
 {
   GError *error = NULL;
 
   secret_service_store_finish (service, result, &error);
 
-  if (error != NULL) {
-LOG ("%s:%d", __func__, __LINE__);
-    g_task_return_error (task, error);
-  }
-  else {
-LOG ("%s:%d", __func__, __LINE__);
-    g_task_return_boolean (task, TRUE);
-  }
-
-  g_object_unref (task);
+  if (error)
+LOG ("[%d] Error storing token in secret schema: %s", __LINE__, error->message);
+  else
+LOG ("[%d] Successfully stored token in secret schema", __LINE__);
 }
 
 void
-ephy_sync_secret_forget_all_tokens (GAsyncReadyCallback callback,
-                                    gpointer            user_data)
+ephy_sync_secret_forget_all_tokens (void)
 {
   GHashTable *attributes;
-  GTask *task;
 
 LOG ("%s:%d", __func__, __LINE__);
 
-  task = g_task_new (NULL, NULL, callback, user_data);
   attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, NULL);
   secret_service_clear (NULL,
                         EPHY_SYNC_TOKEN_SCHEMA,
                         attributes,
                         NULL,
                         (GAsyncReadyCallback) forget_all_tokens_cb,
-                        g_object_ref (task));
+                        NULL);
 
   g_hash_table_unref (attributes);
-  g_object_unref (task);
 }
 
 void
 ephy_sync_secret_load_tokens (EphySyncService *sync_service)
 {
+  SecretItem *secret_item;
+  SecretValue *secret_value;
   GHashTable *attributes;
+  GError *error = NULL;
+  GList *matches;
+  GList *tmp;
+  EphySyncTokenType token_type;
+  const gchar *emailUTF8;
+  const gchar *token_value;
+  const gchar *token_name;
+  gchar *user_email;
 
+  user_email = ephy_sync_service_get_user_email (sync_service);
   attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, NULL);
 
-  secret_service_search (NULL,
-                         EPHY_SYNC_TOKEN_SCHEMA,
-                         attributes,
-                         SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
-                         NULL,
-                         (GAsyncReadyCallback) load_tokens_cb,
-                         sync_service);
+  /* Do this synchronously so the tokens will be available immediately */
+  matches = secret_service_search_sync (NULL,
+                                        EPHY_SYNC_TOKEN_SCHEMA,
+                                        attributes,
+                                        SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | 
SECRET_SEARCH_LOAD_SECRETS,
+                                        NULL,
+                                        &error);
 
-  g_hash_table_unref (attributes);
+  for (tmp = matches; tmp != NULL; tmp = tmp->next) {
+    secret_item = tmp->data;
+
+    attributes = secret_item_get_attributes (secret_item);
+    emailUTF8 = g_hash_table_lookup (attributes, EMAIL_KEY);
+    token_type = g_ascii_strtoull (g_hash_table_lookup (attributes, TOKEN_TYPE_KEY),
+                                   NULL, 10);
+    token_name = g_hash_table_lookup (attributes, TOKEN_NAME_KEY);
+    secret_value = secret_item_get_secret (secret_item);
+    token_value = secret_value_get_text (secret_value);
+
+    /* Sanity check */
+    if (g_strcmp0 (emailUTF8, user_email))
+      continue;
+
+    ephy_sync_service_save_token (sync_service, token_type, g_strdup (token_value));
+LOG ("[%d] Loaded token %s with value %s for email %s", __LINE__, token_name, token_value, emailUTF8);
+
+    g_hash_table_unref (attributes);
+  }
+
+  g_list_free_full (matches, g_object_unref);
 }
 
 void
-ephy_sync_secret_store_token (const gchar         *emailUTF8,
-                              const gchar         *token_name,
-                              const gchar         *token_value,
-                              GAsyncReadyCallback  callback,
-                              gpointer             user_data)
+ephy_sync_secret_store_token (const gchar       *emailUTF8,
+                              EphySyncTokenType  token_type,
+                              gchar             *token_value)
 {
   SecretValue *secret_value;
   GHashTable *attributes;
-  GTask *task;
+  const gchar *token_name;
   gchar *label;
 
-  g_return_if_fail (token_name);
+  g_return_if_fail (emailUTF8);
   g_return_if_fail (token_value);
 
-LOG ("%s:%d", __func__, __LINE__);
+LOG ("[%d] Storing token %s with value %s for email %s ", __LINE__, ephy_sync_utils_token_name_from_type 
(token_type), token_value, emailUTF8);
 
-  task = g_task_new (NULL, NULL, callback, user_data);
+  token_name = ephy_sync_utils_token_name_from_type (token_type);
   secret_value = secret_value_new (token_value, -1, "text/plain");
   attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA,
                                         EMAIL_KEY, emailUTF8,
-                                        TOKEN_KEY, token_name,
+                                        TOKEN_TYPE_KEY, token_type,
+                                        TOKEN_NAME_KEY, token_name,
                                         NULL);
-LOG ("size: %u", g_hash_table_size (attributes));
   /* Translators: The %s is the name of the token whose value is stored.
    * Example: quickStretchedPW or authPW
    */
@@ -193,10 +169,9 @@ LOG ("size: %u", g_hash_table_size (attributes));
                         secret_value,
                         NULL,
                         (GAsyncReadyCallback) store_token_cb,
-                        g_object_ref (task));
+                        NULL);
 
   g_free (label);
   secret_value_unref (secret_value);
   g_hash_table_unref (attributes);
-  g_object_unref (task);
 }
diff --git a/src/ephy-sync-secret.h b/src/ephy-sync-secret.h
index 1fc5ee1..5885f77 100644
--- a/src/ephy-sync-secret.h
+++ b/src/ephy-sync-secret.h
@@ -28,21 +28,19 @@ G_BEGIN_DECLS
 
 const SecretSchema *ephy_sync_secret_get_token_schema (void) G_GNUC_CONST;
 
-#define EMAIL_KEY "email_utf8"
-#define TOKEN_KEY "token_name"
+#define EMAIL_KEY      "email_utf8"
+#define TOKEN_TYPE_KEY "token_type"
+#define TOKEN_NAME_KEY "token_name"
 
 #define EPHY_SYNC_TOKEN_SCHEMA (ephy_sync_secret_get_token_schema ())
 
-void ephy_sync_secret_forget_all_tokens (GAsyncReadyCallback callback,
-                                         gpointer            userdata);
+void ephy_sync_secret_forget_all_tokens (void);
 
 void ephy_sync_secret_load_tokens       (EphySyncService *sync_service);
 
-void ephy_sync_secret_store_token       (const gchar         *emailUTF8,
-                                         const gchar         *token_name,
-                                         const gchar         *token_value,
-                                         GAsyncReadyCallback  callback,
-                                         gpointer             userdata);
+void ephy_sync_secret_store_token       (const gchar       *emailUTF8,
+                                         EphySyncTokenType  token_type,
+                                         gchar             *token_value);
 
 G_END_DECLS
 
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index 4035f27..4e339b2 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -17,6 +17,8 @@
  */
 
 #include "ephy-debug.h"
+#include "ephy-prefs.h"
+#include "ephy-settings.h"
 #include "ephy-sync-crypto.h"
 #include "ephy-sync-secret.h"
 #include "ephy-sync-service.h"
@@ -26,6 +28,14 @@
 #include <libsoup/soup.h>
 #include <string.h>
 
+struct _EphySyncService {
+  GObject parent_instance;
+
+  gchar *user_email;
+  GHashTable *tokens;
+};
+
+
 G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
 
 static void
@@ -50,9 +60,19 @@ ephy_sync_service_class_init (EphySyncServiceClass *klass)
 static void
 ephy_sync_service_init (EphySyncService *self)
 {
+  gchar *sync_user = NULL;
+
   self->tokens = g_hash_table_new_full (NULL, g_str_equal,
                                         NULL, g_free);
 
+  sync_user = g_settings_get_string (EPHY_SETTINGS_MAIN,
+                                     EPHY_PREFS_SYNC_USER);
+
+  if (sync_user && sync_user[0]) {
+    ephy_sync_service_set_user_email (self, sync_user);
+    ephy_sync_secret_load_tokens (self);
+  }
+
 LOG ("%s:%d", __func__, __LINE__);
 }
 
@@ -77,34 +97,68 @@ ephy_sync_service_new (void)
 }
 
 gchar *
-ephy_sync_service_get_token (EphySyncService *self,
-                             const gchar     *token_name)
+ephy_sync_service_get_user_email (EphySyncService *self)
 {
-  GHashTableIter iter;
-  gchar *key, *value;
+  return self->user_email;
+}
 
-  g_hash_table_iter_init (&iter, self->tokens);
+void
+ephy_sync_service_set_user_email (EphySyncService *self,
+                                  const gchar     *emailUTF8)
+{
+  g_free (self->user_email);
+  self->user_email = g_strdup (emailUTF8);
+}
 
-  while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
-      if (g_strcmp0 (token_name, key) == 0) {
-LOG ("[%d] Returning token %s with value %s", __LINE__, key, value);
-        return value;
-      }
-  }
+gchar *
+ephy_sync_service_get_token (EphySyncService   *self,
+                             EphySyncTokenType  token_type)
+{
+  const gchar *token_name;
+  gchar *token_value;
+
+  token_name = ephy_sync_utils_token_name_from_type (token_type);
+  token_value = (gchar *) g_hash_table_lookup (self->tokens, token_name);
 
-  return NULL;
+LOG ("[%d] Returning token %s with value %s", __LINE__, token_name, token_value);
+
+  return token_value;
 }
 
 void
-ephy_sync_service_set_token (EphySyncService *self,
-                             const gchar     *token_name,
-                             const gchar     *token_value_hex)
+ephy_sync_service_save_token (EphySyncService   *self,
+                              EphySyncTokenType  token_type,
+                              gchar             *token_value)
 {
+  const gchar *token_name;
+
+LOG ("[%d] token_type: %d", __LINE__, token_type);
+  token_name = ephy_sync_utils_token_name_from_type (token_type);
   g_hash_table_insert (self->tokens,
                        (gpointer) token_name,
-                       (gpointer) token_value_hex);
+                       (gpointer) token_value);
 
-LOG ("[%d] Set token %s with value %s", __LINE__, token_name, token_value_hex);
+LOG ("[%d] Saved token %s with value %s", __LINE__, token_name, token_value);
+}
+
+void
+ephy_sync_service_delete_token (EphySyncService   *self,
+                                EphySyncTokenType  token_type)
+{
+  const gchar *token_name;
+
+  token_name = ephy_sync_utils_token_name_from_type (token_type);
+  g_hash_table_remove (self->tokens, token_name);
+
+LOG ("[%d] Deleted token %s", __LINE__, token_name);
+}
+
+void
+ephy_sync_service_delete_all_tokens (EphySyncService *self)
+{
+  g_hash_table_remove_all (self->tokens);
+
+LOG ("[%d] Deleted all tokens", __LINE__);
 }
 
 void
@@ -115,8 +169,6 @@ ephy_sync_service_login (EphySyncService *self)
   gchar *request_body;
   gchar *authPW;
 
-  g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
-
 LOG ("%s:%d Preparing soup message", __func__, __LINE__);
 
   session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT,
@@ -125,7 +177,7 @@ LOG ("%s:%d Preparing soup message", __func__, __LINE__);
   message = soup_message_new (SOUP_METHOD_POST,
                               "https://api.accounts.firefox.com/v1/account/login";);
 
-  authPW = ephy_sync_service_get_token (self, "authPW");
+  authPW = ephy_sync_service_get_token (self, EPHY_SYNC_TOKEN_AUTHPW);
   g_assert (authPW != NULL);
 
   request_body = g_strconcat ("{\"authPW\": \"",
@@ -195,24 +247,6 @@ ephy_sync_utils_display_hex ("quickStretchedPW", quickStretchedPW, EPHY_SYNC_TOK
                          unwrapBKey,
                          EPHY_SYNC_TOKEN_LENGTH);
 
-  self->user_email = g_strdup (emailUTF8);
-  ephy_sync_service_set_token (self, "quickStretchedPW", ephy_sync_utils_encode_hex (quickStretchedPW, 
EPHY_SYNC_TOKEN_LENGTH));
-  ephy_sync_service_set_token (self, "authPW", ephy_sync_utils_encode_hex (authPW, EPHY_SYNC_TOKEN_LENGTH));
-  ephy_sync_service_set_token (self, "unwrapBKey", ephy_sync_utils_encode_hex (unwrapBKey, 
EPHY_SYNC_TOKEN_LENGTH));
-
-  ephy_sync_secret_store_token (self->user_email,
-                                "quickStretchedPW",
-                                ephy_sync_service_get_token (self, "quickStretchedPW"),
-                                NULL, NULL);
-  ephy_sync_secret_store_token (self->user_email,
-                                "authPW",
-                                ephy_sync_service_get_token (self, "authPW"),
-                                NULL, NULL);
-  ephy_sync_secret_store_token (self->user_email,
-                                "unwrapBKey",
-                                ephy_sync_service_get_token (self, "unwrapBKey"),
-                                NULL, NULL);
-
   g_free (salt_stretch);
   g_free (info_unwrap);
   g_free (info_auth);
diff --git a/src/ephy-sync-service.h b/src/ephy-sync-service.h
index c35a924..e467c83 100644
--- a/src/ephy-sync-service.h
+++ b/src/ephy-sync-service.h
@@ -19,35 +19,40 @@
 #ifndef EPHY_SYNC_SERVICE_H
 #define EPHY_SYNC_SERVICE_H
 
+#include "ephy-sync-utils.h"
+
 #include <glib-object.h>
 
 G_BEGIN_DECLS
 
-struct _EphySyncService {
-  GObject parent_instance;
-
-  gchar *user_email;
-  GHashTable *tokens;
-};
-
 #define EPHY_TYPE_SYNC_SERVICE (ephy_sync_service_get_type ())
 
 G_DECLARE_FINAL_TYPE (EphySyncService, ephy_sync_service, EPHY, SYNC_SERVICE, GObject)
 
-EphySyncService *ephy_sync_service_new       (void);
+EphySyncService *ephy_sync_service_new               (void);
+
+gchar           *ephy_sync_service_get_user_email    (EphySyncService *self);
+
+void             ephy_sync_service_set_user_email    (EphySyncService *self,
+                                                      const gchar     *emailUTF8);
+
+gchar           *ephy_sync_service_get_token         (EphySyncService   *self,
+                                                      EphySyncTokenType  token_type);
+
+void             ephy_sync_service_save_token        (EphySyncService   *self,
+                                                      EphySyncTokenType  token_type,
+                                                      gchar             *token_value);
 
-gchar           *ephy_sync_service_get_token (EphySyncService *self,
-                                              const gchar     *token_name);
+void             ephy_sync_service_delete_token      (EphySyncService   *self,
+                                                      EphySyncTokenType  token_type);
 
-void             ephy_sync_service_set_token (EphySyncService *self,
-                                              const gchar     *token_name,
-                                              const gchar     *token_value_hex);
+void             ephy_sync_service_delete_all_tokens (EphySyncService *self);
 
-void             ephy_sync_service_stretch   (EphySyncService *self,
-                                              const gchar     *emailUTF8,
-                                              const gchar     *passwordUTF8);
+void             ephy_sync_service_stretch           (EphySyncService *self,
+                                                      const gchar     *emailUTF8,
+                                                      const gchar     *passwordUTF8);
 
-void             ephy_sync_service_login     (EphySyncService *self);
+void             ephy_sync_service_login             (EphySyncService *self);
 
 G_END_DECLS
 
diff --git a/src/ephy-sync-utils.c b/src/ephy-sync-utils.c
index 33ad8f9..152dddb 100644
--- a/src/ephy-sync-utils.c
+++ b/src/ephy-sync-utils.c
@@ -72,6 +72,23 @@ ephy_sync_utils_decode_hex (const gchar *hex_string)
   return retval;
 }
 
+const gchar *
+ephy_sync_utils_token_name_from_type (EphySyncTokenType token_type)
+{
+  switch (token_type) {
+  case EPHY_SYNC_TOKEN_AUTHPW:
+    return "authPw";
+  case EPHY_SYNC_TOKEN_SESSIONTOKEN:
+    return "sessionToken";
+  case EPHY_SYNC_TOKEN_UNWRAPBKEY:
+    return "unwrapBKey";
+  case EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW:
+    return "quickStretchedPW";
+  default:
+    g_assert_not_reached ();
+  }
+}
+
 /* FIXME: Only for debugging, remove when no longer needed */
 void
 ephy_sync_utils_display_hex (const gchar *data_name,
diff --git a/src/ephy-sync-utils.h b/src/ephy-sync-utils.h
index 9ea089c..ea0b6f5 100644
--- a/src/ephy-sync-utils.h
+++ b/src/ephy-sync-utils.h
@@ -25,20 +25,29 @@ G_BEGIN_DECLS
 
 #define EPHY_SYNC_TOKEN_LENGTH 32
 
-gchar  *ephy_sync_utils_kw          (const gchar *name);
+typedef enum {
+  EPHY_SYNC_TOKEN_AUTHPW,
+  EPHY_SYNC_TOKEN_SESSIONTOKEN,
+  EPHY_SYNC_TOKEN_UNWRAPBKEY,
+  EPHY_SYNC_TOKEN_QUICKSTRETCHEDPW
+} EphySyncTokenType;
 
-gchar  *ephy_sync_utils_kwe         (const gchar *name,
-                                     const gchar *emailUTF8);
+gchar       *ephy_sync_utils_kw                   (const gchar *name);
 
-gchar  *ephy_sync_utils_encode_hex  (guint8 *data,
-                                     gsize   data_length);
+gchar       *ephy_sync_utils_kwe                  (const gchar *name,
+                                                   const gchar *emailUTF8);
 
-guint8 *ephy_sync_utils_decode_hex  (const gchar *hex_string);
+gchar       *ephy_sync_utils_encode_hex           (guint8 *data,
+                                                   gsize   data_length);
+
+guint8      *ephy_sync_utils_decode_hex           (const gchar *hex_string);
+
+const gchar *ephy_sync_utils_token_name_from_type (EphySyncTokenType token_type);
 
 /* FIXME: Only for debugging, remove when no longer needed */
-void    ephy_sync_utils_display_hex (const gchar *data_name,
-                                     guint8      *data,
-                                     gsize        data_length);
+void         ephy_sync_utils_display_hex          (const gchar *data_name,
+                                                   guint8      *data,
+                                                   gsize        data_length);
 
 G_END_DECLS
 


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