[epiphany/wip/sync: 37/86] sync: Move sign in logic to EphySyncService



commit e9ae0ec01fff6ac46fadb5f5507b52d228447534
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Tue Mar 7 16:46:06 2017 +0200

    sync: Move sign in logic to EphySyncService
    
    Also, poll Firefox Accounts Server asynchronously

 src/prefs-dialog.c           |  161 ++++--------------------
 src/sync/ephy-sync-service.c |  279 +++++++++++++++++++++++++++++-------------
 src/sync/ephy-sync-service.h |   10 +--
 3 files changed, 219 insertions(+), 231 deletions(-)
---
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index 376696d..003af7d 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -51,7 +51,6 @@
 #include <string.h>
 
 #ifdef ENABLE_SYNC
-#include "ephy-sync-crypto.h"
 #include "ephy-sync-secret.h"
 #include "ephy-sync-service.h"
 #endif
@@ -127,26 +126,10 @@ struct _PrefsDialog {
   WebKitWebView *fxa_web_view;
   WebKitUserContentManager *fxa_manager;
   WebKitUserScript *fxa_script;
-  guint fxa_source_id;
 #endif
   GtkWidget *notebook;
 };
 
-#ifdef ENABLE_SYNC
-typedef struct {
-  PrefsDialog *dialog;
-  char        *email;
-  char        *uid;
-  char        *sessionToken;
-  char        *keyFetchToken;
-  char        *unwrapBKey;
-  guint8      *tokenID;
-  guint8      *reqHMACkey;
-  guint8      *respHMACkey;
-  guint8      *respXORkey;
-} FxACallbackData;
-#endif
-
 enum {
   COL_TITLE_ELIDED,
   COL_ENCODING,
@@ -155,59 +138,6 @@ enum {
 
 G_DEFINE_TYPE (PrefsDialog, prefs_dialog, GTK_TYPE_DIALOG)
 
-#ifdef ENABLE_SYNC
-static FxACallbackData *
-fxa_callback_data_new (PrefsDialog *dialog,
-                       const char  *email,
-                       const char  *uid,
-                       const char  *sessionToken,
-                       const char  *keyFetchToken,
-                       const char  *unwrapBKey,
-                       guint8      *tokenID,
-                       guint8      *reqHMACkey,
-                       guint8      *respHMACkey,
-                       guint8      *respXORkey)
-{
-  FxACallbackData *data = g_slice_new (FxACallbackData);
-
-  data->dialog = g_object_ref (dialog);
-  data->email = g_strdup (email);
-  data->uid = g_strdup (uid);
-  data->sessionToken = g_strdup (sessionToken);
-  data->keyFetchToken = g_strdup (keyFetchToken);
-  data->unwrapBKey = g_strdup (unwrapBKey);
-  data->tokenID = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->tokenID, tokenID, EPHY_SYNC_TOKEN_LENGTH);
-  data->reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->reqHMACkey, reqHMACkey, EPHY_SYNC_TOKEN_LENGTH);
-  data->respHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->respHMACkey, respHMACkey, EPHY_SYNC_TOKEN_LENGTH);
-  data->respXORkey = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
-  memcpy (data->respXORkey, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
-
-  return data;
-}
-
-static void
-fxa_callback_data_free (FxACallbackData *data)
-{
-  g_assert (data != NULL);
-
-  g_object_unref (data->dialog);
-  g_free (data->email);
-  g_free (data->uid);
-  g_free (data->sessionToken);
-  g_free (data->keyFetchToken);
-  g_free (data->unwrapBKey);
-  g_free (data->tokenID);
-  g_free (data->reqHMACkey);
-  g_free (data->respHMACkey);
-  g_free (data->respXORkey);
-
-  g_slice_free (FxACallbackData, data);
-}
-#endif
-
 static void
 prefs_dialog_finalize (GObject *object)
 {
@@ -231,11 +161,6 @@ prefs_dialog_finalize (GObject *object)
     webkit_user_script_unref (dialog->fxa_script);
     g_object_unref (dialog->fxa_manager);
   }
-
-  if (dialog->fxa_source_id != 0) {
-    g_source_remove (dialog->fxa_source_id);
-    dialog->fxa_source_id = 0;
-  }
 #endif
 
   G_OBJECT_CLASS (prefs_dialog_parent_class)->finalize (object);
@@ -243,6 +168,25 @@ prefs_dialog_finalize (GObject *object)
 
 #ifdef ENABLE_SYNC
 static void
+sync_sign_in_error_cb (EphySyncService *service,
+                       const char      *error,
+                       PrefsDialog     *dialog)
+{
+  char *message;
+
+  g_assert (EPHY_IS_SYNC_SERVICE (service));
+  g_assert (EPHY_IS_PREFS_DIALOG (dialog));
+
+  /* Display the error message to the user. */
+  message = g_strdup_printf ("<span fgcolor='#e6780b'>%s</span>", error);
+  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 void
 hide_fxa_iframe (PrefsDialog *dialog,
                  const char  *email)
 {
@@ -299,33 +243,6 @@ sync_tokens_store_finished_cb (EphySyncService *service,
   }
 }
 
-static gboolean
-poll_fxa_server (gpointer user_data)
-{
-  FxACallbackData *data;
-  EphySyncService *service;
-  char *bundle;
-
-  data = (FxACallbackData *)user_data;
-  service = ephy_shell_get_sync_service (ephy_shell_get_default ());
-  bundle = ephy_sync_service_start_sign_in (service, data->tokenID, data->reqHMACkey);
-
-  if (bundle != NULL) {
-    ephy_sync_service_finish_sign_in (service, data->email, data->uid,
-                                      data->sessionToken, data->keyFetchToken,
-                                      data->unwrapBKey, bundle,
-                                      data->respHMACkey, data->respXORkey);
-
-    g_free (bundle);
-    data->dialog->fxa_source_id = 0;
-    fxa_callback_data_free (data);
-
-    return G_SOURCE_REMOVE;
-  }
-
-  return G_SOURCE_CONTINUE;
-}
-
 static void
 inject_data_to_server (PrefsDialog *dialog,
                        const char  *type,
@@ -384,7 +301,6 @@ server_message_received_cb (WebKitUserContentManager *manager,
 
   if (g_strcmp0 (command, "loaded") == 0) {
     LOG ("Loaded Firefox Sign In iframe");
-    gtk_widget_set_visible (dialog->sync_sign_in_details, FALSE);
   } else if (g_strcmp0 (command, "can_link_account") == 0) {
     /* We need to confirm a relink. */
     inject_data_to_server (dialog, "message", "can_link_account", "{'ok': true}");
@@ -395,12 +311,9 @@ server_message_received_cb (WebKitUserContentManager *manager,
     const char *sessionToken = json_object_get_string_member (data, "sessionToken");
     const char *keyFetchToken = json_object_get_string_member (data, "keyFetchToken");
     const char *unwrapBKey = json_object_get_string_member (data, "unwrapBKey");
-    guint8 *tokenID;
-    guint8 *reqHMACkey;
-    guint8 *respHMACkey;
-    guint8 *respXORkey;
     char *text;
 
+    gtk_widget_set_visible (dialog->sync_sign_in_details, FALSE);
     inject_data_to_server (dialog, "message", "login", NULL);
 
     /* Cannot retrieve the sync keys without keyFetchToken or unwrapBKey. */
@@ -419,40 +332,15 @@ server_message_received_cb (WebKitUserContentManager *manager,
       goto out;
     }
 
-    /* Derive tokenID, reqHMACkey, respHMACkey and respXORkey from the keyFetchToken.
-     * tokenID and reqHMACkey are used to make a HAWK request to the "GET /account/keys"
-     * API. The server looks up the stored table entry with tokenID, checks the request
-     * HMAC for validity, then returns the pre-encrypted response.
-     * See https://github.com/mozilla/fxa-auth-server/wiki/onepw-protocol#fetching-sync-keys */
-    ephy_sync_crypto_process_key_fetch_token (keyFetchToken,
-                                              &tokenID, &reqHMACkey,
-                                              &respHMACkey, &respXORkey);
-
-    /* If the account is not verified, then poll the server repeatedly
-     * until the verification has finished. */
     if (json_object_get_boolean_member (data, "verified") == FALSE) {
-      FxACallbackData *cb_data;
-
       text = g_strdup_printf ("<span fgcolor='#e6780b'>%s</span>",
                               _("Please don’t leave this page until you have completed the verification."));
       gtk_label_set_markup (GTK_LABEL (dialog->sync_sign_in_details), text);
       gtk_widget_set_visible (dialog->sync_sign_in_details, TRUE);
-
-      cb_data = fxa_callback_data_new (dialog, email, uid, sessionToken,
-                                       keyFetchToken, unwrapBKey, tokenID,
-                                       reqHMACkey, respHMACkey, respXORkey);
-      dialog->fxa_source_id = g_timeout_add_seconds (2, (GSourceFunc)poll_fxa_server, cb_data);
-
-      g_free (text);
-    } else {
-      char *bundle;
-
-      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);
-
-      g_free (bundle);
     }
+
+    ephy_sync_service_do_sign_in (service, email, uid,
+                                  sessionToken, keyFetchToken, unwrapBKey);
   } else if (g_strcmp0 (command, "session_status") == 0) {
     /* We are not signed in at this time, which we signal by returning an error. */
     inject_data_to_server (dialog, "message", "error", NULL);
@@ -1662,6 +1550,9 @@ setup_sync_page (PrefsDialog *dialog)
   g_signal_connect_object (service, "sync-tokens-store-finished",
                            G_CALLBACK (sync_tokens_store_finished_cb),
                            dialog, 0);
+  g_signal_connect_object (service, "sync-sign-in-error",
+                           G_CALLBACK (sync_sign_in_error_cb),
+                           dialog, 0);
 }
 #endif
 
diff --git a/src/sync/ephy-sync-service.c b/src/sync/ephy-sync-service.c
index def23d5..d2864b3 100644
--- a/src/sync/ephy-sync-service.c
+++ b/src/sync/ephy-sync-service.c
@@ -75,6 +75,7 @@ G_DEFINE_TYPE (EphySyncService, ephy_sync_service, G_TYPE_OBJECT);
 enum {
   STORE_FINISHED,
   LOAD_FINISHED,
+  SIGN_IN_ERROR,
   LAST_SIGNAL
 };
 
@@ -91,6 +92,18 @@ typedef struct {
   gpointer             user_data;
 } StorageRequestAsyncData;
 
+typedef struct {
+  char   *email;
+  char   *uid;
+  char   *sessionToken;
+  char   *keyFetchToken;
+  char   *unwrapBKey;
+  char   *tokenID_hex;
+  guint8 *reqHMACkey;
+  guint8 *respHMACkey;
+  guint8 *respXORkey;
+} SignInAsyncData;
+
 static void ephy_sync_service_send_next_storage_request (EphySyncService *self);
 
 static StorageRequestAsyncData *
@@ -126,6 +139,54 @@ storage_server_request_async_data_free (StorageRequestAsyncData *data)
   g_slice_free (StorageRequestAsyncData, data);
 }
 
+static SignInAsyncData *
+sign_in_async_data_new (const char   *email,
+                        const char   *uid,
+                        const char   *sessionToken,
+                        const char   *keyFetchToken,
+                        const char   *unwrapBKey,
+                        const char   *tokenID_hex,
+                        const guint8 *reqHMACkey,
+                        const guint8 *respHMACkey,
+                        const guint8 *respXORkey)
+{
+  SignInAsyncData *data;
+
+  data = g_slice_new (SignInAsyncData);
+  data->email = g_strdup (email);
+  data->uid = g_strdup (uid);
+  data->sessionToken = g_strdup (sessionToken);
+  data->keyFetchToken = g_strdup (keyFetchToken);
+  data->unwrapBKey = g_strdup (unwrapBKey);
+  data->tokenID_hex = g_strdup (tokenID_hex);
+  data->reqHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+  memcpy (data->reqHMACkey, reqHMACkey, EPHY_SYNC_TOKEN_LENGTH);
+  data->respHMACkey = g_malloc (EPHY_SYNC_TOKEN_LENGTH);
+  memcpy (data->respHMACkey, respHMACkey, EPHY_SYNC_TOKEN_LENGTH);
+  data->respXORkey = g_malloc (2 * EPHY_SYNC_TOKEN_LENGTH);
+  memcpy (data->respXORkey, respXORkey, 2 * EPHY_SYNC_TOKEN_LENGTH);
+
+  return data;
+}
+
+static void
+sign_in_async_data_free (SignInAsyncData *data)
+{
+  g_assert (data != NULL);
+
+  g_free (data->email);
+  g_free (data->uid);
+  g_free (data->sessionToken);
+  g_free (data->keyFetchToken);
+  g_free (data->unwrapBKey);
+  g_free (data->tokenID_hex);
+  g_free (data->reqHMACkey);
+  g_free (data->respHMACkey);
+  g_free (data->respXORkey);
+
+  g_slice_free (SignInAsyncData, data);
+}
+
 static gboolean
 ephy_sync_service_storage_credentials_is_expired (EphySyncService *self)
 {
@@ -180,19 +241,18 @@ ephy_sync_service_fxa_hawk_post_async (EphySyncService     *self,
   ephy_sync_crypto_hawk_header_free (hheader);
 }
 
-static guint
-ephy_sync_service_fxa_hawk_get_sync (EphySyncService  *self,
-                                     const char       *endpoint,
-                                     const char       *id,
-                                     guint8           *key,
-                                     gsize             key_length,
-                                     JsonNode        **node)
+static void
+ephy_sync_service_fxa_hawk_get_async (EphySyncService     *self,
+                                      const char          *endpoint,
+                                      const char          *id,
+                                      guint8              *key,
+                                      gsize                key_length,
+                                      SoupSessionCallback  callback,
+                                      gpointer             user_data)
 {
   EphySyncCryptoHawkHeader *hheader;
   SoupMessage *msg;
-  JsonParser *parser;
   char *url;
-  guint retval;
 
   g_assert (EPHY_IS_SYNC_SERVICE (self));
   g_assert (endpoint);
@@ -203,22 +263,10 @@ ephy_sync_service_fxa_hawk_get_sync (EphySyncService  *self,
   msg = soup_message_new (SOUP_METHOD_GET, url);
   hheader = ephy_sync_crypto_compute_hawk_header (url, "GET", id, key, key_length, NULL);
   soup_message_headers_append (msg->request_headers, "authorization", hheader->header);
-  soup_session_send_message (self->session, msg);
-
-  if (node) {
-    parser = json_parser_new ();
-    json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
-    *node = json_node_copy (json_parser_get_root (parser));
-    g_object_unref (parser);
-  }
-
-  retval = msg->status_code;
+  soup_session_queue_message (self->session, msg, callback, user_data);
 
   g_free (url);
-  g_object_unref (msg);
   ephy_sync_crypto_hawk_header_free (hheader);
-
-  return retval;
 }
 
 static gboolean
@@ -611,6 +659,14 @@ ephy_sync_service_class_init (EphySyncServiceClass *klass)
                   0, NULL, NULL, NULL,
                   G_TYPE_NONE, 1,
                   G_TYPE_ERROR);
+
+  signals[SIGN_IN_ERROR] =
+    g_signal_new ("sync-sign-in-error",
+                  EPHY_TYPE_SYNC_SERVICE,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_STRING);
 }
 
 static void
@@ -850,50 +906,10 @@ ephy_sync_service_destroy_session (EphySyncService *self,
   g_free (url);
 }
 
-char *
-ephy_sync_service_start_sign_in (EphySyncService  *self,
-                                 guint8           *tokenID,
-                                 guint8           *reqHMACkey)
-{
-  JsonNode *node;
-  JsonObject *json;
-  char *tokenID_hex;
-  char *bundle = NULL;
-  guint status_code;
-
-  /* Retrieve the sync keys bundle from the /account/keys endpoint. */
-  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
-  status_code = ephy_sync_service_fxa_hawk_get_sync (self, "account/keys", tokenID_hex,
-                                                     reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
-                                                     &node);
-  json = json_node_get_object (node);
-
-  if (status_code == 200) {
-    bundle = g_strdup (json_object_get_string_member (json, "bundle"));
-  } else {
-    LOG ("Failed to retrieve sync keys bundle: code: %ld, errno: %ld, error: '%s', message: '%s'",
-         json_object_get_int_member (json, "code"),
-         json_object_get_int_member (json, "errno"),
-         json_object_get_string_member (json, "error"),
-         json_object_get_string_member (json, "message"));
-  }
-
-  g_free (tokenID_hex);
-  json_node_free (node);
-
-  return bundle;
-}
-
-void
-ephy_sync_service_finish_sign_in (EphySyncService *self,
-                                  const char      *email,
-                                  const char      *uid,
-                                  const char      *sessionToken,
-                                  const char      *keyFetchToken,
-                                  const char      *unwrapBKey,
-                                  char            *bundle,
-                                  guint8          *respHMACkey,
-                                  guint8          *respXORkey)
+static void
+ephy_sync_service_conclude_sign_in (EphySyncService *self,
+                                    SignInAsyncData *data,
+                                    const char      *bundle)
 {
   guint8 *unwrapKB;
   guint8 *kA;
@@ -901,43 +917,130 @@ ephy_sync_service_finish_sign_in (EphySyncService *self,
   char *kA_hex;
   char *kB_hex;
 
-  g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
-  g_return_if_fail (email);
-  g_return_if_fail (uid);
-  g_return_if_fail (sessionToken);
-  g_return_if_fail (keyFetchToken);
-  g_return_if_fail (unwrapBKey);
-  g_return_if_fail (bundle);
-  g_return_if_fail (respHMACkey);
-  g_return_if_fail (respXORkey);
-
-  /* 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,
+  g_assert (EPHY_IS_SYNC_SERVICE (self));
+  g_assert (data);
+  g_assert (bundle);
+
+  /* Derive the master sync keys form the key bundle. */
+  unwrapKB = ephy_sync_crypto_decode_hex (data->unwrapBKey);
+  ephy_sync_crypto_compute_sync_keys (bundle, data->respHMACkey,
+                                      data->respXORkey, unwrapKB,
                                       &kA, &kB);
   kA_hex = ephy_sync_crypto_encode_hex (kA, 0);
   kB_hex = ephy_sync_crypto_encode_hex (kB, 0);
 
   /* 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_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);
+  g_settings_set_string (EPHY_SETTINGS_MAIN, EPHY_PREFS_SYNC_USER, data->email);
+  ephy_sync_service_set_user_email (self, data->email);
+  ephy_sync_service_set_token (self, data->uid, TOKEN_UID);
+  ephy_sync_service_set_token (self, data->sessionToken, TOKEN_SESSIONTOKEN);
+  ephy_sync_service_set_token (self, data->keyFetchToken, TOKEN_KEYFETCHTOKEN);
+  ephy_sync_service_set_token (self, data->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);
+  ephy_sync_secret_store_tokens (self, data->email, data->uid,
+                                 data->sessionToken, data->keyFetchToken,
+                                 data->unwrapBKey, kA_hex, kB_hex);
 
   g_free (kA);
   g_free (kB);
   g_free (kA_hex);
   g_free (kB_hex);
   g_free (unwrapKB);
+  sign_in_async_data_free (data);
+}
+
+static void
+get_account_keys_cb (SoupSession *session,
+                     SoupMessage *msg,
+                     gpointer     user_data)
+{
+  EphySyncService *service;
+  SignInAsyncData *data;
+  JsonParser *parser;
+  JsonObject *json;
+  GError *error = NULL;
+
+  service = ephy_shell_get_sync_service (ephy_shell_get_default ());
+  data = (SignInAsyncData *)user_data;
+  parser = json_parser_new ();
+  json_parser_load_from_data (parser, msg->response_body->data, -1, &error);
+
+  if (error) {
+    g_warning ("Failed to parse JSON: %s", error->message);
+    g_error_free (error);
+    goto out;
+  }
+
+  json = json_node_get_object (json_parser_get_root (parser));
+
+  if (msg->status_code == 200) {
+    /* Extract the master sync keys from the bundle and save tokens. */
+    ephy_sync_service_conclude_sign_in (service, data,
+                                        json_object_get_string_member (json, "bundle"));
+  } else if (msg->status_code == 400 && json_object_get_int_member (json, "errno") == 104) {
+    /* Poll the Firefox Accounts Server until the user verifies the account. */
+    LOG ("Account not verified, retrying...");
+    ephy_sync_service_fxa_hawk_get_async (service, "account/keys", data->tokenID_hex,
+                                          data->reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
+                                          get_account_keys_cb, data);
+  } else {
+    /* Translators: the %s represents the server returned error. */
+    char *message = g_strdup_printf (_("Failed to get the master sync key bundle: %s"),
+                                     json_object_get_string_member (json, "error"));
+    g_signal_emit (service, signals[SIGN_IN_ERROR], 0, message);
+    ephy_sync_service_destroy_session (service, data->sessionToken);
+    g_free (message);
+    sign_in_async_data_free (data);
+  }
+
+out:
+  g_object_unref (parser);
+}
+
+void
+ephy_sync_service_do_sign_in (EphySyncService *self,
+                              const char      *email,
+                              const char      *uid,
+                              const char      *sessionToken,
+                              const char      *keyFetchToken,
+                              const char      *unwrapBKey)
+{
+  SignInAsyncData *data;
+  guint8 *tokenID;
+  guint8 *reqHMACkey;
+  guint8 *respHMACkey;
+  guint8 *respXORkey;
+  char *tokenID_hex;
+
+  g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
+  g_return_if_fail (email);
+  g_return_if_fail (uid);
+  g_return_if_fail (sessionToken);
+  g_return_if_fail (keyFetchToken);
+  g_return_if_fail (unwrapBKey);
+
+  /* Derive tokenID, reqHMACkey, respHMACkey and respXORkey from keyFetchToken.
+   * tokenID and reqHMACkey are used to sign a HAWK GET requests to the /account/keys
+   * endpoint. The server looks up the stored table entry with tokenID, checks
+   * the request HMAC for validity, then returns the pre-encrypted response.
+   * See https://github.com/mozilla/fxa-auth-server/wiki/onepw-protocol#fetching-sync-keys */
+  ephy_sync_crypto_process_key_fetch_token (keyFetchToken,
+                                            &tokenID, &reqHMACkey,
+                                            &respHMACkey, &respXORkey);
+  tokenID_hex = ephy_sync_crypto_encode_hex (tokenID, 0);
+
+  /* Get the master sync key bundle from the /account/keys endpoint. */
+  data = sign_in_async_data_new (email, uid, sessionToken,
+                                 keyFetchToken, unwrapBKey, tokenID_hex,
+                                 reqHMACkey, respHMACkey, respXORkey);
+  ephy_sync_service_fxa_hawk_get_async (self, "account/keys", tokenID_hex,
+                                        reqHMACkey, EPHY_SYNC_TOKEN_LENGTH,
+                                        get_account_keys_cb, data);
+
+  g_free (tokenID_hex);
 }
 
 static void
diff --git a/src/sync/ephy-sync-service.h b/src/sync/ephy-sync-service.h
index bb3041f..a50fd3b 100644
--- a/src/sync/ephy-sync-service.h
+++ b/src/sync/ephy-sync-service.h
@@ -49,18 +49,12 @@ void             ephy_sync_service_clear_storage_credentials    (EphySyncService
 void             ephy_sync_service_clear_tokens                 (EphySyncService *self);
 void             ephy_sync_service_destroy_session              (EphySyncService *self,
                                                                  const char      *sessionToken);
-char            *ephy_sync_service_start_sign_in                (EphySyncService  *self,
-                                                                 guint8           *tokenID,
-                                                                 guint8           *reqHMACkey);
-void             ephy_sync_service_finish_sign_in               (EphySyncService *self,
+void             ephy_sync_service_do_sign_in                   (EphySyncService *self,
                                                                  const char      *email,
                                                                  const char      *uid,
                                                                  const char      *sessionToken,
                                                                  const char      *keyFetchToken,
-                                                                 const char      *unwrapBKey,
-                                                                 char            *bundle,
-                                                                 guint8          *respHMACkey,
-                                                                 guint8          *respXORkey);
+                                                                 const char      *unwrapBKey);
 void             ephy_sync_service_upload_bookmark              (EphySyncService *self,
                                                                  EphyBookmark    *bookmark,
                                                                  gboolean         force);


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