[epiphany/wip/sync: 3/4] sync: Make sure secrets are cleared only after they are no longer needed
- From: Gabriel Ivașcu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/sync: 3/4] sync: Make sure secrets are cleared only after they are no longer needed
- Date: Thu, 8 Jun 2017 13:41:37 +0000 (UTC)
commit 8480e0c71e69044324977d8213fe14bd90c63544
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Thu Jun 8 14:58:04 2017 +0300
sync: Make sure secrets are cleared only after they are no longer needed
This prevents situations when the session token is needed to obtain a
signed certificate + storage credentials to unregister the device at
sign out, but the session token had already been deleted. More specifically,
this is the case when the async requests take too long and the session
token ends up being deleted by _forget_tokens() before the requests complete.
lib/sync/ephy-sync-service.c | 160 +++++++++++++++++++++++++++---------------
1 files changed, 104 insertions(+), 56 deletions(-)
---
diff --git a/lib/sync/ephy-sync-service.c b/lib/sync/ephy-sync-service.c
index b371f1e..ac34b8b 100644
--- a/lib/sync/ephy-sync-service.c
+++ b/lib/sync/ephy-sync-service.c
@@ -606,15 +606,62 @@ out:
}
static void
+forget_secrets_cb (SecretService *service,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ secret_service_clear_finish (service, result, &error);
+ if (error) {
+ g_warning ("Failed to clear sync secrets: %s", error->message);
+ g_error_free (error);
+ } else {
+ LOG ("Successfully cleared sync secrets");
+ }
+}
+
+static void
+ephy_sync_service_forget_secrets (EphySyncService *self)
+{
+ GHashTable *attributes;
+ char *user;
+
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+ g_assert (self->secrets);
+
+ user = ephy_sync_utils_get_sync_user ();
+ g_assert (user);
+ attributes = secret_attributes_build (EPHY_SYNC_SECRET_SCHEMA,
+ ACCOUNT_KEY, user,
+ NULL);
+ secret_service_clear (NULL, EPHY_SYNC_SECRET_SCHEMA, attributes, NULL,
+ (GAsyncReadyCallback)forget_secrets_cb, NULL);
+ g_hash_table_remove_all (self->secrets);
+
+ g_hash_table_unref (attributes);
+ g_free (user);
+}
+
+static void
destroy_session_cb (SoupSession *session,
SoupMessage *msg,
gpointer user_data)
{
- if (msg->status_code != 200)
+ EphySyncService *self = EPHY_SYNC_SERVICE (user_data);
+
+ if (msg->status_code != 200) {
g_warning ("Failed to destroy session. Status code: %u, response: %s",
msg->status_code, msg->response_body->data);
- else
+ } else {
LOG ("Successfully destroyed session");
+ }
+
+ /* This is the last step of signing out. Sync secrets can be deleted now. */
+ ephy_sync_service_forget_secrets (self);
+ ephy_sync_service_clear_storage_credentials (self);
+ ephy_sync_utils_set_device_id (NULL);
+ ephy_sync_utils_set_sync_user (NULL);
}
static void
@@ -657,7 +704,7 @@ ephy_sync_service_destroy_session (EphySyncService *self,
"authorization", hawk_header->header);
soup_message_headers_append (msg->request_headers,
"content-type", content_type);
- soup_session_queue_message (self->session, msg, destroy_session_cb, NULL);
+ soup_session_queue_message (self->session, msg, destroy_session_cb, self);
g_free (token_id_hex);
g_free (token_id);
@@ -1360,41 +1407,6 @@ sync_frequency_changed_cb (GSettings *settings,
}
static void
-forget_secrets_cb (SecretService *service,
- GAsyncResult *result,
- gpointer user_data)
-{
- GError *error = NULL;
-
- secret_service_clear_finish (service, result, &error);
- if (error) {
- g_warning ("Failed to clear sync secrets: %s", error->message);
- g_error_free (error);
- }
-}
-
-static void
-ephy_sync_service_forget_secrets (EphySyncService *self)
-{
- GHashTable *attributes;
- char *user;
-
- g_assert (EPHY_IS_SYNC_SERVICE (self));
- g_assert (self->secrets);
-
- user = ephy_sync_utils_get_sync_user ();
- attributes = secret_attributes_build (EPHY_SYNC_SECRET_SCHEMA,
- ACCOUNT_KEY, user,
- NULL);
- secret_service_clear (NULL, EPHY_SYNC_SECRET_SCHEMA, attributes, NULL,
- (GAsyncReadyCallback)forget_secrets_cb, NULL);
- g_hash_table_remove_all (self->secrets);
-
- g_hash_table_unref (attributes);
- g_free (user);
-}
-
-static void
load_secrets_cb (SecretService *service,
GAsyncResult *result,
EphySyncService *self)
@@ -2213,24 +2225,68 @@ ephy_sync_service_register_device (EphySyncService *self,
}
static void
-ephy_sync_service_unregister_device (EphySyncService *self)
+delete_open_tabs_record_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
{
- char *id;
+ EphySyncService *self = EPHY_SYNC_SERVICE (user_data);
+
+ if (msg->status_code != 200) {
+ g_warning ("Failed to delete open tabs record. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ } else {
+ LOG ("Successfully deleted open tabs record");
+ }
+
+ ephy_sync_service_destroy_session (self, NULL);
+
+ /* This is the last storage message of this session, clear queue. */
+ while (!g_queue_is_empty (self->storage_queue))
+ storage_request_async_data_free (g_queue_pop_head (self->storage_queue));
+
+}
+
+static void
+unregister_device_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ EphySyncService *self = EPHY_SYNC_SERVICE (user_data);
char *endpoint;
+ char *id;
- g_assert (EPHY_IS_SYNC_SERVICE (self));
+ if (msg->status_code != 200) {
+ g_warning ("Failed to unregister device. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+ } else {
+ LOG ("Successfully unregistered device");
+ }
+ /* Delete the open tabs record corresponding to this device. */
id = ephy_sync_utils_get_device_id ();
- endpoint = g_strdup_printf ("storage/clients/%s", id);
+ endpoint = g_strdup_printf ("storage/tabs/%s", id);
ephy_sync_service_queue_storage_request (self, endpoint, SOUP_METHOD_DELETE,
- NULL, -1, -1, NULL, NULL);
+ NULL, -1, -1,
+ delete_open_tabs_record_cb, self);
g_free (endpoint);
- endpoint = g_strdup_printf ("storage/tabs/%s", id);
- ephy_sync_service_queue_storage_request (self, endpoint, SOUP_METHOD_DELETE,
- NULL, -1, -1, NULL, NULL);
+ g_free (id);
+}
- ephy_sync_utils_set_device_id (NULL);
+static void
+ephy_sync_service_unregister_device (EphySyncService *self)
+{
+ char *endpoint;
+ char *id;
+
+ g_assert (EPHY_IS_SYNC_SERVICE (self));
+
+ id = ephy_sync_utils_get_device_id ();
+ endpoint = g_strdup_printf ("storage/clients/%s", id);
+ ephy_sync_service_queue_storage_request (self, endpoint,
+ SOUP_METHOD_DELETE,
+ NULL, -1, -1,
+ unregister_device_cb, self);
g_free (endpoint);
g_free (id);
@@ -2241,15 +2297,8 @@ ephy_sync_service_do_sign_out (EphySyncService *self)
{
g_return_if_fail (EPHY_IS_SYNC_SERVICE (self));
- ephy_sync_service_unregister_device (self);
ephy_sync_service_stop_periodical_sync (self);
- ephy_sync_service_destroy_session (self, NULL);
- ephy_sync_service_clear_storage_credentials (self);
- ephy_sync_service_forget_secrets (self);
-
- /* Clear storage messages queue. */
- while (!g_queue_is_empty (self->storage_queue))
- storage_request_async_data_free (g_queue_pop_head (self->storage_queue));
+ ephy_sync_service_unregister_device (self);
/* Clear managers. */
for (GSList *l = self->managers; l && l->data; l = l->next) {
@@ -2258,7 +2307,6 @@ ephy_sync_service_do_sign_out (EphySyncService *self)
}
g_clear_pointer (&self->managers, g_slist_free);
- ephy_sync_utils_set_sync_user (NULL);
ephy_sync_utils_set_bookmarks_sync_is_initial (TRUE);
ephy_sync_utils_set_passwords_sync_is_initial (TRUE);
ephy_sync_utils_set_history_sync_is_initial (TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]