[epiphany] sync: Handle failure of sync-secret's store/load functions



commit d6b2a70b036df6961502289d2be0e923369f7697
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Thu Nov 24 22:53:23 2016 +0200

    sync: Handle failure of sync-secret's store/load functions
    
    On store: Don't validate the sign in unless the tokens were successfully
    stored. The tokens are now stored together as a JSON (this way they all
    succeed or all fail to be stored).
    
    On load: Notify the user to sign in again if the tokens fail to load.

 src/ephy-shell.c             |   40 ++++++--
 src/prefs-dialog.c           |   41 +++++++-
 src/sync/ephy-sync-secret.c  |  238 +++++++++++++++++++++++++++++------------
 src/sync/ephy-sync-secret.h  |   11 ++-
 src/sync/ephy-sync-service.c |   94 +++++++++--------
 src/sync/ephy-sync-service.h |    6 +-
 src/sync/ephy-sync-utils.c   |   20 ++++
 src/sync/ephy-sync-utils.h   |   29 +++---
 8 files changed, 331 insertions(+), 148 deletions(-)
---
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 3e29127..486517c 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -47,6 +47,10 @@
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 
+#ifdef ENABLE_SYNC
+#include "ephy-notification.h"
+#endif
+
 struct _EphyShell {
   EphyEmbedShell parent_instance;
 
@@ -309,6 +313,29 @@ download_started_cb (WebKitWebContext *web_context,
   g_object_unref (ephy_download);
 }
 
+#ifdef ENABLE_SYNC
+static void
+sync_tokens_load_finished_cb (EphySyncService *service,
+                              GError          *error,
+                              gpointer         user_data)
+{
+  EphyNotification *notification;
+
+  g_assert (EPHY_IS_SYNC_SERVICE (service));
+
+  /* If the tokens were successfully loaded, start the periodical sync.
+   * Otherwise, notify the user to sign in again. */
+  if (error == NULL) {
+    ephy_sync_service_start_periodical_sync (service, TRUE);
+  } else {
+    notification = ephy_notification_new (error->message,
+                                          _("Please visit Preferences and sign in "
+                                            "again to continue the sync process."));
+    ephy_notification_show (notification);
+  }
+}
+#endif
+
 static void
 ephy_shell_startup (GApplication *application)
 {
@@ -331,10 +358,6 @@ ephy_shell_startup (GApplication *application)
 
   mode = ephy_embed_shell_get_mode (embed_shell);
   if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION) {
-#ifdef ENABLE_SYNC
-    EphySyncService *service;
-#endif
-
     g_action_map_add_action_entries (G_ACTION_MAP (application),
                                      app_entries, G_N_ELEMENTS (app_entries),
                                      application);
@@ -352,10 +375,11 @@ ephy_shell_startup (GApplication *application)
     }
 
 #ifdef ENABLE_SYNC
-    /* Start the periodical sync now. */
-    service = ephy_sync_service_new ();
-    ephy_sync_service_start_periodical_sync (service, TRUE);
-    ephy_shell->sync_service = service;
+    /* Create the sync service. */
+    ephy_shell->sync_service = ephy_sync_service_new ();
+    g_signal_connect (ephy_shell->sync_service,
+                      "sync-tokens-load-finished",
+                      G_CALLBACK (sync_tokens_load_finished_cb), NULL);
 #endif
 
     builder = gtk_builder_new ();
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index 314a519..b49dff1 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -258,6 +258,41 @@ hide_fxa_iframe (PrefsDialog *dialog,
   g_free (account);
 }
 
+static void
+sync_tokens_store_finished_cb (EphySyncService *service,
+                               GError          *error,
+                               PrefsDialog     *dialog)
+{
+  g_assert (EPHY_IS_SYNC_SERVICE (service));
+  g_assert (EPHY_IS_PREFS_DIALOG (dialog));
+
+  if (error == NULL) {
+    /* Show the 'Signed in' panel. */
+    hide_fxa_iframe (dialog, ephy_sync_service_get_user_email (service));
+
+    /* Do a first time sync and set a periodical sync to be executed. */
+    ephy_sync_service_sync_bookmarks (service, TRUE);
+    ephy_sync_service_start_periodical_sync (service, FALSE);
+  } else {
+    char *message;
+
+    /* Destroy the current session. */
+    ephy_sync_service_destroy_session (service, NULL);
+
+    /* Unset the email and tokens. */
+    g_settings_set_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_USER, "");
+    ephy_sync_service_clear_tokens (service);
+
+    /* Display the error message to the user. */
+    message = g_strdup_printf ("<span fgcolor='#e6780b'>%s</span>", error->message);
+    gtk_label_set_markup (GTK_LABEL (dialog->sync_sign_in_details), message);
+    gtk_widget_set_visible (dialog->sync_sign_in_details, TRUE);
+    webkit_web_view_load_uri (dialog->fxa_web_view, FXA_IFRAME_URL);
+
+    g_free (message);
+  }
+}
+
 static gboolean
 poll_fxa_server (gpointer user_data)
 {
@@ -274,7 +309,6 @@ poll_fxa_server (gpointer user_data)
                                       data->sessionToken, data->keyFetchToken,
                                       data->unwrapBKey, bundle,
                                       data->respHMACkey, data->respXORkey);
-    hide_fxa_iframe (data->dialog, data->email);
 
     g_free (bundle);
     fxa_callback_data_free (data);
@@ -410,7 +444,6 @@ server_message_received_cb (WebKitUserContentManager *manager,
       bundle = ephy_sync_service_start_sign_in (service, tokenID, reqHMACkey);
       ephy_sync_service_finish_sign_in (service, email, uid, sessionToken, keyFetchToken,
                                         unwrapBKey, bundle, respHMACkey, respXORkey);
-      hide_fxa_iframe (dialog, email);
 
       g_free (bundle);
     }
@@ -1745,6 +1778,10 @@ setup_sync_page (PrefsDialog *dialog)
     g_free (text);
     g_free (account);
   }
+
+  g_signal_connect_object (service, "sync-tokens-store-finished",
+                           G_CALLBACK (sync_tokens_store_finished_cb),
+                           dialog, 0);
 }
 #endif
 
diff --git a/src/sync/ephy-sync-secret.c b/src/sync/ephy-sync-secret.c
index a1ea2b9..a5f82de 100644
--- a/src/sync/ephy-sync-secret.c
+++ b/src/sync/ephy-sync-secret.c
@@ -23,47 +23,40 @@
 
 #include <glib/gi18n.h>
 
+GQuark sync_secret_error_quark (void);
+G_DEFINE_QUARK (sync-secret-error-quark, sync_secret_error)
+#define SYNC_SECRET_ERROR sync_secret_error_quark ()
+
+enum {
+  SYNC_SECRET_ERROR_STORE = 101,
+  SYNC_SECRET_ERROR_LOAD = 102
+};
+
 const SecretSchema *
 ephy_sync_secret_get_token_schema (void)
 {
   static const SecretSchema schema = {
-    "org.epiphany.SyncToken", SECRET_SCHEMA_NONE,
+    "org.epiphany.SyncTokens", SECRET_SCHEMA_NONE,
     {
-      { EMAIL_KEY,      SECRET_SCHEMA_ATTRIBUTE_STRING },
-      { TOKEN_TYPE_KEY, SECRET_SCHEMA_ATTRIBUTE_INTEGER },
-      { TOKEN_NAME_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
+      { EMAIL_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING },
       { "NULL", 0 },
     }
   };
+
   return &schema;
 }
 
 static void
-forget_all_tokens_cb (SecretService *service,
-                      GAsyncResult  *result,
-                      gpointer       user_data)
+forget_tokens_cb (SecretService *service,
+                  GAsyncResult  *result,
+                  gpointer       user_data)
 {
   GError *error = NULL;
 
   secret_service_clear_finish (service, result, &error);
 
   if (error != NULL) {
-    g_warning ("Failed to clear token secret schema: %s", error->message);
-    g_error_free (error);
-  }
-}
-
-static void
-store_token_cb (SecretService *service,
-                GAsyncResult  *result,
-                gpointer       user_data)
-{
-  GError *error = NULL;
-
-  secret_service_store_finish (service, result, &error);
-
-  if (error != NULL) {
-    g_warning ("Failed to store token in secret schema: %s", error->message);
+    g_warning ("sync-secret: Failed to clear the secret schema: %s", error->message);
     g_error_free (error);
   }
 }
@@ -75,86 +68,191 @@ ephy_sync_secret_forget_tokens (void)
 
   attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, NULL);
   secret_service_clear (NULL, EPHY_SYNC_TOKEN_SCHEMA, attributes,
-                        NULL, (GAsyncReadyCallback) forget_all_tokens_cb, NULL);
+                        NULL, (GAsyncReadyCallback)forget_tokens_cb, NULL);
 
   g_hash_table_unref (attributes);
 }
 
-void
-ephy_sync_secret_load_tokens (EphySyncService *service)
+static void
+load_tokens_cb (SecretService *service,
+                GAsyncResult  *result,
+                gpointer       user_data)
 {
-  SecretItem *secret_item;
-  SecretValue *secret_value;
+  EphySyncService *sync_service = EPHY_SYNC_SERVICE (user_data);
+  SecretItem *item;
   GHashTable *attributes;
+  SecretValue *value = NULL;
+  JsonParser *parser = NULL;
+  JsonObject *json;
+  GList *matches = NULL;
+  GList *members = NULL;
   GError *error = NULL;
-  GList *matches;
-  EphySyncTokenType type;
+  GError *ret_error = NULL;
+  const char *tokens;
   const char *email;
-  const char *value;
   char *user_email;
 
-  user_email = ephy_sync_service_get_user_email (service);
-  attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA, NULL);
+  matches = secret_service_search_finish (service, result, &error);
 
-  /* 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);
+  if (error != NULL || matches == NULL) {
+    g_set_error (&ret_error,
+                 SYNC_SECRET_ERROR,
+                 SYNC_SECRET_ERROR_LOAD,
+                 _("The sync tokens could not be found."));
+    if (error != NULL)
+      g_warning ("sync-secret: Failed to find the tokens: %s", error->message);
+    goto out;
+  }
 
-  if (error != NULL) {
-    g_warning ("Failed to search for attributes: %s", error->message);
-    g_error_free (error);
-    return;
+  if (g_list_length (matches) > 1) {
+    g_set_error (&ret_error,
+                 SYNC_SECRET_ERROR,
+                 SYNC_SECRET_ERROR_LOAD,
+                 _("Found more than one set of sync tokens."));
+    g_warning ("sync-secret: Was expecting exactly one match, found more.");
+    goto out;
   }
 
-  for (GList *m = matches; m != NULL; m = m->next) {
-    secret_item = m->data;
-    attributes = secret_item_get_attributes (secret_item);
-    email = g_hash_table_lookup (attributes, EMAIL_KEY);
-    type = g_ascii_strtoull (g_hash_table_lookup (attributes, TOKEN_TYPE_KEY), NULL, 10);
-    secret_value = secret_item_get_secret (secret_item);
-    value = secret_value_get_text (secret_value);
+  item = (SecretItem *)matches->data;
+  attributes = secret_item_get_attributes (item);
+  email = g_hash_table_lookup (attributes, EMAIL_KEY);
+  user_email = ephy_sync_service_get_user_email (sync_service);
 
-    /* Sanity check */
-    if (g_strcmp0 (email, user_email) != 0)
-      continue;
+  if (email == NULL || g_strcmp0 (email, user_email) != 0) {
+    g_set_error (&ret_error,
+                 SYNC_SECRET_ERROR,
+                 SYNC_SECRET_ERROR_LOAD,
+                 _("Could not found the sync tokens for the currently logged in user."));
+    g_warning ("sync-secret: Emails differ: %s vs %s", email, user_email);
+    goto out;
+  }
 
-    ephy_sync_service_set_token (service, g_strdup (value), type);
-    g_hash_table_unref (attributes);
+  value = secret_item_get_secret (item);
+  if (value == NULL) {
+    g_set_error (&ret_error,
+                 SYNC_SECRET_ERROR,
+                 SYNC_SECRET_ERROR_LOAD,
+                 _("Could not get the secret value of the sync tokens."));
+    g_warning ("sync-secret: The secret item of the tokens has a NULL value.");
+    goto out;
+  }
+
+  parser = json_parser_new ();
+  tokens = secret_value_get_text (value);
+  json_parser_load_from_data (parser, tokens, -1, &error);
+
+  if (error != NULL) {
+    g_set_error (&ret_error,
+                 SYNC_SECRET_ERROR,
+                 SYNC_SECRET_ERROR_LOAD,
+                 _("The sync tokens are not a valid JSON."));
+    g_warning ("sync-secret: Failed to load JSON from data: %s", error->message);
+    goto out;
   }
 
+  json = json_node_get_object (json_parser_get_root (parser));
+  members = json_object_get_members (json);
+
+  /* Set the tokens. */
+  for (GList *m = members; m != NULL; m = m->next) {
+    ephy_sync_service_set_token (sync_service,
+                                 json_object_get_string_member (json, m->data),
+                                 ephy_sync_utils_token_type_from_name (m->data));
+  }
+
+out:
+  /* Notify whether the tokens were successfully loaded. */
+  g_signal_emit_by_name (sync_service, "sync-tokens-load-finished", ret_error);
+
+  if (error != NULL)
+    g_error_free (error);
+
+  if (ret_error != NULL)
+    g_error_free (ret_error);
+
+  if (value != NULL)
+    secret_value_unref (value);
+
+  if (parser != NULL)
+    g_object_unref (parser);
+
+  g_list_free (members);
   g_list_free_full (matches, g_object_unref);
 }
 
 void
-ephy_sync_secret_store_token (const char        *email,
-                              char              *value,
-                              EphySyncTokenType  type)
+ephy_sync_secret_load_tokens (EphySyncService *service)
+{
+  GHashTable *attributes;
+
+  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, service);
+
+  g_hash_table_unref (attributes);
+}
+
+static void
+store_tokens_cb (SecretService *service,
+                 GAsyncResult  *result,
+                 gpointer       user_data)
+{
+  EphySyncService *sync_service = EPHY_SYNC_SERVICE (user_data);
+  GError *error = NULL;
+
+  secret_service_store_finish (service, result, &error);
+
+  /* Notify whether the tokens were successfully stored. */
+  g_signal_emit_by_name (sync_service, "sync-tokens-store-finished", error);
+
+  if (error != NULL)
+    g_error_free (error);
+}
+
+void
+ephy_sync_secret_store_tokens (EphySyncService *service,
+                               const char      *email,
+                               const char      *uid,
+                               const char      *sessionToken,
+                               const char      *keyFetchToken,
+                               const char      *unwrapBKey,
+                               const char      *kA,
+                               const char      *kB)
 {
-  SecretValue *secret_value;
+  SecretValue *value;
   GHashTable *attributes;
-  const char *name;
+  char *tokens;
   char *label;
 
-  g_return_if_fail (email);
-  g_return_if_fail (value);
+  g_return_if_fail (email != NULL);
+  g_return_if_fail (uid != NULL);
+  g_return_if_fail (sessionToken != NULL);
+  g_return_if_fail (keyFetchToken != NULL);
+  g_return_if_fail (unwrapBKey != NULL);
+  g_return_if_fail (kA != NULL);
+  g_return_if_fail (kB != NULL);
 
-  name = ephy_sync_utils_token_name_from_type (type);
-  secret_value = secret_value_new (value, -1, "text/plain");
+  tokens = ephy_sync_utils_build_json_string ("uid", uid,
+                                              "sessionToken", sessionToken,
+                                              "keyFetchToken", keyFetchToken,
+                                              "unwrapBKey", unwrapBKey,
+                                              "kA", kA,
+                                              "kB", kB,
+                                              NULL);
+  value = secret_value_new (tokens, -1, "text/plain");
   attributes = secret_attributes_build (EPHY_SYNC_TOKEN_SCHEMA,
                                         EMAIL_KEY, email,
-                                        TOKEN_TYPE_KEY, type,
-                                        TOKEN_NAME_KEY, name,
                                         NULL);
-  /* Translators: secret token description stored in gnome-keyring.
-   * The %s represents the name of the token, e.g. sessionToken. */
-  label = g_strdup_printf (_("Token value for %s token"), name);
+  /* Translators: The %s represents the email of the user. */
+  label = g_strdup_printf (_("The sync tokens of %s"), email);
 
   secret_service_store (NULL, EPHY_SYNC_TOKEN_SCHEMA, attributes,
-                        NULL, label, secret_value, NULL,
-                        (GAsyncReadyCallback) store_token_cb, NULL);
+                        NULL, label, value, NULL,
+                        (GAsyncReadyCallback)store_tokens_cb, service);
 
+  g_free (tokens);
   g_free (label);
-  secret_value_unref (secret_value);
+  secret_value_unref (value);
   g_hash_table_unref (attributes);
 }
diff --git a/src/sync/ephy-sync-secret.h b/src/sync/ephy-sync-secret.h
index 9d035f9..f540c8e 100644
--- a/src/sync/ephy-sync-secret.h
+++ b/src/sync/ephy-sync-secret.h
@@ -37,8 +37,13 @@ const SecretSchema *ephy_sync_secret_get_token_schema (void) G_GNUC_CONST;
 
 void ephy_sync_secret_forget_tokens (void);
 void ephy_sync_secret_load_tokens   (EphySyncService *service);
-void ephy_sync_secret_store_token   (const char        *email,
-                                     char              *value,
-                                     EphySyncTokenType  type);
+void ephy_sync_secret_store_tokens  (EphySyncService *service,
+                                     const char      *email,
+                                     const char      *uid,
+                                     const char      *sessionToken,
+                                     const char      *keyFetchToken,
+                                     const char      *unwrapBKey,
+                                     const char      *kA,
+                                     const char      *kB);
 
 G_END_DECLS
diff --git a/src/sync/ephy-sync-service.c b/src/sync/ephy-sync-service.c
index 2e98b50..49cef51 100644
--- a/src/sync/ephy-sync-service.c
+++ b/src/sync/ephy-sync-service.c
@@ -70,6 +70,14 @@ struct _EphySyncService {
 
 G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
 
+enum {
+  STORE_FINISHED,
+  LOAD_FINISHED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
 typedef struct {
   EphySyncService     *service;
   char                *endpoint;
@@ -609,6 +617,22 @@ ephy_sync_service_class_init (EphySyncServiceClass *klass)
 
   object_class->finalize = ephy_sync_service_finalize;
   object_class->dispose = ephy_sync_service_dispose;
+
+  signals[STORE_FINISHED] =
+    g_signal_new ("sync-tokens-store-finished",
+                  EPHY_TYPE_SYNC_SERVICE,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_ERROR);
+
+  signals[LOAD_FINISHED] =
+    g_signal_new ("sync-tokens-load-finished",
+                  EPHY_TYPE_SYNC_SERVICE,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_ERROR);
 }
 
 static void
@@ -716,7 +740,7 @@ ephy_sync_service_get_token (EphySyncService   *self,
 
 void
 ephy_sync_service_set_token (EphySyncService   *self,
-                             char              *value,
+                             const char        *value,
                              EphySyncTokenType  type)
 {
   g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
@@ -725,27 +749,27 @@ ephy_sync_service_set_token (EphySyncService   *self,
   switch (type) {
     case TOKEN_UID:
       g_free (self->uid);
-      self->uid = value;
+      self->uid = g_strdup (value);
       break;
     case TOKEN_SESSIONTOKEN:
       g_free (self->sessionToken);
-      self->sessionToken = value;
+      self->sessionToken = g_strdup (value);
       break;
     case TOKEN_KEYFETCHTOKEN:
       g_free (self->keyFetchToken);
-      self->keyFetchToken = value;
+      self->keyFetchToken = g_strdup (value);
       break;
     case TOKEN_UNWRAPBKEY:
       g_free (self->unwrapBKey);
-      self->unwrapBKey = value;
+      self->unwrapBKey = g_strdup (value);
       break;
     case TOKEN_KA:
       g_free (self->kA);
-      self->kA = value;
+      self->kA = g_strdup (value);
       break;
     case TOKEN_KB:
       g_free (self->kB);
-      self->kB = value;
+      self->kB = g_strdup (value);
       break;
     default:
       g_assert_not_reached ();
@@ -753,31 +777,6 @@ ephy_sync_service_set_token (EphySyncService   *self,
 }
 
 void
-ephy_sync_service_set_and_store_tokens (EphySyncService   *self,
-                                        char              *value,
-                                        EphySyncTokenType  type,
-                                        ...)
-{
-  EphySyncTokenType next_type;
-  char *next_value;
-  va_list args;
-
-  g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
-  g_return_if_fail (value != NULL);
-
-  ephy_sync_service_set_token (self, value, type);
-  ephy_sync_secret_store_token (self->user_email, value, type);
-
-  va_start (args, type);
-  while ((next_value = va_arg (args, char *)) != NULL) {
-    next_type = va_arg (args, EphySyncTokenType);
-    ephy_sync_service_set_token (self, next_value, next_type);
-    ephy_sync_secret_store_token (self->user_email, next_value, next_type);
-  }
-  va_end (args);
-}
-
-void
 ephy_sync_service_clear_storage_credentials (EphySyncService *self)
 {
   g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
@@ -897,6 +896,8 @@ ephy_sync_service_finish_sign_in (EphySyncService *self,
   guint8 *unwrapKB;
   guint8 *kA;
   guint8 *kB;
+  char *kA_hex;
+  char *kB_hex;
 
   g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
   g_return_if_fail (email != NULL);
@@ -908,31 +909,32 @@ ephy_sync_service_finish_sign_in (EphySyncService *self,
   g_return_if_fail (respHMACkey != NULL);
   g_return_if_fail (respXORkey != NULL);
 
-
   /* Derive the sync keys form the received key bundle. */
   unwrapKB = ephy_sync_crypto_decode_hex (unwrapBKey);
   ephy_sync_crypto_compute_sync_keys (bundle,
                                       respHMACkey, respXORkey, unwrapKB,
                                       &kA, &kB);
+  kA_hex = ephy_sync_crypto_encode_hex (kA, 0);
+  kB_hex = ephy_sync_crypto_encode_hex (kB, 0);
 
-  /* Save the tokens. */
+  /* Save the email and the tokens. */
   g_settings_set_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_USER, email);
   ephy_sync_service_set_user_email (self, email);
-  ephy_sync_service_set_and_store_tokens (self,
-                                          g_strdup (uid), TOKEN_UID,
-                                          g_strdup (sessionToken), TOKEN_SESSIONTOKEN,
-                                          g_strdup (keyFetchToken), TOKEN_KEYFETCHTOKEN,
-                                          g_strdup (unwrapBKey), TOKEN_UNWRAPBKEY,
-                                          ephy_sync_crypto_encode_hex (kA, 0), TOKEN_KA,
-                                          ephy_sync_crypto_encode_hex (kB, 0), TOKEN_KB,
-                                          NULL);
-
-  /* Do a first time sync and set a periodical sync afterwards. */
-  ephy_sync_service_sync_bookmarks (self, TRUE);
-  ephy_sync_service_start_periodical_sync (self, FALSE);
+  ephy_sync_service_set_token (self, uid, TOKEN_UID);
+  ephy_sync_service_set_token (self, sessionToken, TOKEN_SESSIONTOKEN);
+  ephy_sync_service_set_token (self, keyFetchToken, TOKEN_KEYFETCHTOKEN);
+  ephy_sync_service_set_token (self, unwrapBKey, TOKEN_UNWRAPBKEY);
+  ephy_sync_service_set_token (self, kA_hex, TOKEN_KA);
+  ephy_sync_service_set_token (self, kB_hex, TOKEN_KB);
+
+  /* Store the tokens in the secret schema. */
+  ephy_sync_secret_store_tokens (self, email, uid, sessionToken,
+                                 keyFetchToken, unwrapBKey, kA_hex, kB_hex);
 
   g_free (kA);
   g_free (kB);
+  g_free (kA_hex);
+  g_free (kB_hex);
   g_free (unwrapKB);
 }
 
diff --git a/src/sync/ephy-sync-service.h b/src/sync/ephy-sync-service.h
index 333ac5d..cd1fabb 100644
--- a/src/sync/ephy-sync-service.h
+++ b/src/sync/ephy-sync-service.h
@@ -43,12 +43,8 @@ void             ephy_sync_service_set_sync_time                (EphySyncService
 char            *ephy_sync_service_get_token                    (EphySyncService   *self,
                                                                  EphySyncTokenType  type);
 void             ephy_sync_service_set_token                    (EphySyncService   *self,
-                                                                 char              *value,
+                                                                 const char        *value,
                                                                  EphySyncTokenType  type);
-void             ephy_sync_service_set_and_store_tokens         (EphySyncService   *self,
-                                                                 char              *value,
-                                                                 EphySyncTokenType  type,
-                                                                 ...) G_GNUC_NULL_TERMINATED;
 void             ephy_sync_service_clear_storage_credentials    (EphySyncService *self);
 void             ephy_sync_service_clear_tokens                 (EphySyncService *self);
 void             ephy_sync_service_destroy_session              (EphySyncService *self,
diff --git a/src/sync/ephy-sync-utils.c b/src/sync/ephy-sync-utils.c
index 74d5f00..35a9ff1 100644
--- a/src/sync/ephy-sync-utils.c
+++ b/src/sync/ephy-sync-utils.c
@@ -112,6 +112,26 @@ ephy_sync_utils_token_name_from_type (EphySyncTokenType type)
   }
 }
 
+EphySyncTokenType
+ephy_sync_utils_token_type_from_name (const char *name)
+{
+  if (g_strcmp0 (name, "uid") == 0) {
+    return TOKEN_UID;
+  } else if (g_strcmp0 (name, "sessionToken") == 0) {
+    return TOKEN_SESSIONTOKEN;
+  } else if (g_strcmp0 (name, "keyFetchToken") == 0) {
+    return TOKEN_KEYFETCHTOKEN;
+  } else if (g_strcmp0 (name, "unwrapBKey") == 0) {
+    return TOKEN_UNWRAPBKEY;
+  } else if (g_strcmp0 (name, "kA") == 0) {
+    return TOKEN_KA;
+  } else if (g_strcmp0 (name, "kB") == 0) {
+    return TOKEN_KB;
+  } else {
+    g_assert_not_reached ();
+  }
+}
+
 char *
 ephy_sync_utils_find_and_replace (const char *src,
                                   const char *find,
diff --git a/src/sync/ephy-sync-utils.h b/src/sync/ephy-sync-utils.h
index 0eb35a1..3bc4d82 100644
--- a/src/sync/ephy-sync-utils.h
+++ b/src/sync/ephy-sync-utils.h
@@ -33,19 +33,20 @@ typedef enum {
 
 G_BEGIN_DECLS
 
-char       *ephy_sync_utils_build_json_string    (const char *key,
-                                                  const char *value,
-                                                  ...) G_GNUC_NULL_TERMINATED;
-char       *ephy_sync_utils_create_bso_json      (const char *id,
-                                                  const char *payload);
-char       *ephy_sync_utils_make_audience        (const char *url);
-const char *ephy_sync_utils_token_name_from_type (EphySyncTokenType type);
-char       *ephy_sync_utils_find_and_replace     (const char *src,
-                                                  const char *find,
-                                                  const char *repl);
-guint8     *ephy_sync_utils_concatenate_bytes    (guint8 *bytes,
-                                                  gsize   bytes_len,
-                                                  ...) G_GNUC_NULL_TERMINATED;
-gint64      ephy_sync_utils_current_time_seconds  (void);
+char              *ephy_sync_utils_build_json_string    (const char *key,
+                                                         const char *value,
+                                                         ...) G_GNUC_NULL_TERMINATED;
+char              *ephy_sync_utils_create_bso_json      (const char *id,
+                                                         const char *payload);
+char              *ephy_sync_utils_make_audience        (const char *url);
+const char        *ephy_sync_utils_token_name_from_type (EphySyncTokenType type);
+EphySyncTokenType  ephy_sync_utils_token_type_from_name (const char *name);
+char              *ephy_sync_utils_find_and_replace     (const char *src,
+                                                         const char *find,
+                                                         const char *repl);
+guint8            *ephy_sync_utils_concatenate_bytes    (guint8 *bytes,
+                                                         gsize   bytes_len,
+                                                         ...) G_GNUC_NULL_TERMINATED;
+gint64             ephy_sync_utils_current_time_seconds  (void);
 
 G_END_DECLS


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