[evolution-ews/gnome-3-4] Bug #679303 - Doesn't detect when password has changed



commit 63846f836047ff30e17941e6663b085d4826731d
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jul 3 19:09:33 2012 +0200

    Bug #679303 - Doesn't detect when password has changed

 src/camel/camel-ews-folder.c  |  146 ++++++++++++++++++++++++++++++-----------
 src/camel/camel-ews-store.c   |   78 ++++++++++++++++------
 src/camel/camel-ews-store.h   |    3 +
 src/server/e-ews-connection.c |   23 +++++--
 src/server/e-ews-connection.h |    3 +
 5 files changed, 186 insertions(+), 67 deletions(-)
---
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index b86c1e2..6c7f316 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -390,6 +390,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
 	const gchar *temp;
 	gboolean res;
 	gchar *mime_fname_new = NULL;
+	GError *local_error = NULL;
 
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
 	ews_folder = (CamelEwsFolder *) folder;
@@ -443,11 +444,14 @@ camel_ews_folder_get_message (CamelFolder *folder,
 					  &items,
 					  (ESoapProgressFn) camel_operation_progress,
 					  (gpointer) cancellable,
-					  cancellable, error);
+					  cancellable, &local_error);
 	g_free (mime_dir);
 
-	if (!res)
+	if (!res) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	/* The mime_content actually contains the *filename*, due to the
 	 * streaming hack in ESoapMessage */
@@ -471,12 +475,16 @@ camel_ews_folder_get_message (CamelFolder *folder,
 						  &items_req,
 						  (ESoapProgressFn) camel_operation_progress,
 						  (gpointer) cancellable,
-						  cancellable, error);
+						  cancellable, &local_error);
 		if (!res || (items_req && e_ews_item_get_item_type (items_req->data) == E_EWS_ITEM_TYPE_ERROR)) {
 			if (items_req) {
 				g_object_unref (items_req->data);
 				g_slist_free (items_req);
 			}
+			if (local_error) {
+				camel_ews_store_maybe_disconnect (ews_store, local_error);
+				g_propagate_error (error, local_error);
+			}
 			goto exit;
 		}
 		calendar_item_accept_id = e_ews_item_get_calendar_item_accept_id (items_req->data);
@@ -774,15 +782,29 @@ ews_sync_mi_flags (CamelFolder *folder,
 {
 	CamelEwsStore *ews_store;
 	EEwsConnection *cnc;
+	GError *local_error = NULL;
+	gboolean res;
 
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
+
+	if (!camel_ews_store_connected (ews_store, error)) {
+		return FALSE;
+	}
+
 	cnc = camel_ews_store_get_connection (ews_store);
 
-	return e_ews_connection_update_items (cnc, EWS_PRIORITY_LOW,
+	res = e_ews_connection_update_items (cnc, EWS_PRIORITY_LOW,
 					      "AlwaysOverwrite", "SaveOnly",
 					      NULL, NULL,
 					      msg_update_flags, mi_list, NULL,
-					      cancellable, error);
+					      cancellable, &local_error);
+
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
+
+	return res;
 }
 
 static gboolean
@@ -835,6 +857,9 @@ ews_move_to_junk_folder (CamelFolder *folder,
 	ews_folder = CAMEL_EWS_FOLDER (folder);
 	ews_store = CAMEL_EWS_STORE (parent_store);
 
+	if (!camel_ews_store_connected (ews_store, error))
+		return FALSE;
+
 	cnc = camel_ews_store_get_connection (ews_store);
 
 	if (junk_uids) {
@@ -884,8 +909,10 @@ ews_move_to_junk_folder (CamelFolder *folder,
 			camel_folder_change_info_free (changes);
 		}
 
-		if (local_error)
+		if (local_error) {
+			camel_ews_store_maybe_disconnect (ews_store, local_error);
 			g_propagate_error (error, local_error);
+		}
 
 		g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
 	}
@@ -1089,9 +1116,13 @@ sync_updated_items (CamelEwsFolder *ews_folder,
                     GCancellable *cancellable,
                     GError **error)
 {
+	CamelEwsStore *ews_store;
 	CamelFolder *folder = (CamelFolder *) ews_folder;
 	GSList *items = NULL, *l;
 	GSList *generic_item_ids = NULL, *msg_ids = NULL;
+	GError *local_error = NULL;
+
+	ews_store = CAMEL_EWS_STORE (camel_folder_get_parent_store (folder));
 
 	for (l = updated_items; l != NULL; l = g_slist_next (l)) {
 		EEwsItem *item = (EEwsItem *) l->data;
@@ -1128,21 +1159,29 @@ sync_updated_items (CamelEwsFolder *ews_folder,
 			(g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			 msg_ids, "IdOnly", SUMMARY_MESSAGE_FLAGS,
 			 FALSE, NULL, &items, NULL, NULL,
-			 cancellable, error);
+			 cancellable, &local_error);
 
 	camel_ews_utils_sync_updated_items (ews_folder, items);
 	items = NULL;
-	if (*error)
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	if (generic_item_ids)
 		e_ews_connection_get_items
 			(g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			 generic_item_ids, "IdOnly", SUMMARY_ITEM_FLAGS,
 			 FALSE, NULL, &items, NULL, NULL,
-			 cancellable, error);
+			 cancellable, &local_error);
 	camel_ews_utils_sync_updated_items (ews_folder, items);
 
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
+
 exit:
 	if (msg_ids) {
 		g_slist_foreach (msg_ids, (GFunc) g_free, NULL);
@@ -1162,8 +1201,12 @@ sync_created_items (CamelEwsFolder *ews_folder,
                     GCancellable *cancellable,
                     GError **error)
 {
+	CamelEwsStore *ews_store;
 	GSList *items = NULL, *l;
 	GSList *generic_item_ids = NULL, *msg_ids = NULL, *post_item_ids = NULL;
+	GError *local_error = NULL;
+
+	ews_store = CAMEL_EWS_STORE (camel_folder_get_parent_store (CAMEL_FOLDER (ews_folder)));
 
 	for (l = created_items; l != NULL; l = g_slist_next (l)) {
 		EEwsItem *item = (EEwsItem *) l->data;
@@ -1199,10 +1242,13 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			(g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			 msg_ids, "IdOnly", SUMMARY_MESSAGE_PROPS,
 			 FALSE, NULL, &items, NULL, NULL,
-			 cancellable, error);
+			 cancellable, &local_error);
 
-	if (*error)
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 	items = NULL;
@@ -1212,10 +1258,13 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			(g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			 post_item_ids, "IdOnly", SUMMARY_POSTITEM_PROPS,
 			 FALSE, NULL, &items, NULL, NULL,
-			 cancellable, error);
+			 cancellable, &local_error);
 
-	if (*error)
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 	items = NULL;
@@ -1225,10 +1274,14 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			(g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			 generic_item_ids, "IdOnly", SUMMARY_ITEM_PROPS,
 			 FALSE, NULL, &items, NULL, NULL,
-			 cancellable, error);
+			 cancellable, &local_error);
 
 	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
 exit:
 	if (msg_ids) {
 		g_slist_foreach (msg_ids, (GFunc) g_free, NULL);
@@ -1259,7 +1312,7 @@ ews_refresh_info_sync (CamelFolder *folder,
 	gchar *id;
 	gchar *sync_state;
 	gboolean includes_last_item = FALSE;
-	GError *rerror = NULL;
+	GError *local_error = NULL;
 
 	full_name = camel_folder_get_full_name (folder);
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
@@ -1304,18 +1357,20 @@ ews_refresh_info_sync (CamelFolder *folder,
 							 "IdOnly", NULL,
 							 EWS_MAX_FETCH_COUNT, &includes_last_item,
 							 &items_created, &items_updated,
-							 &items_deleted, cancellable, &rerror);
+							 &items_deleted, cancellable, &local_error);
 
-		if (rerror)
+		if (local_error) {
+			camel_ews_store_maybe_disconnect (ews_store, local_error);
 			break;
+		}
 
 		if (items_deleted)
 			camel_ews_utils_sync_deleted_items (ews_folder, items_deleted);
 
 		if (items_created)
-			sync_created_items (ews_folder, cnc, items_created, cancellable, &rerror);
+			sync_created_items (ews_folder, cnc, items_created, cancellable, &local_error);
 
-		if (rerror) {
+		if (local_error) {
 			if (items_updated) {
 				g_slist_foreach (items_updated, (GFunc) g_object_unref, NULL);
 				g_slist_free (items_updated);
@@ -1325,9 +1380,9 @@ ews_refresh_info_sync (CamelFolder *folder,
 		}
 
 		if (items_updated)
-			sync_updated_items (ews_folder, cnc, items_updated, cancellable, &rerror);
+			sync_updated_items (ews_folder, cnc, items_updated, cancellable, &local_error);
 
-		if (rerror)
+		if (local_error)
 			break;
 
 		total = camel_folder_summary_count (folder->summary);
@@ -1343,10 +1398,10 @@ ews_refresh_info_sync (CamelFolder *folder,
 		camel_folder_summary_touch (folder->summary);
 		camel_folder_summary_save_to_db (folder->summary, NULL);
 
-	} while (!rerror && !includes_last_item);
+	} while (!local_error && !includes_last_item);
 
-	if (rerror)
-		g_propagate_error (error, rerror);
+	if (local_error)
+		g_propagate_error (error, local_error);
 
 	g_mutex_lock (priv->state_lock);
 	priv->refreshing = FALSE;
@@ -1356,7 +1411,7 @@ ews_refresh_info_sync (CamelFolder *folder,
 	g_object_unref (cnc);
 	g_free (id);
 
-	return !rerror;
+	return !local_error;
 }
 
 static gboolean
@@ -1373,6 +1428,7 @@ ews_append_message_sync (CamelFolder *folder,
 	CamelAddress *from;
 	CamelEwsStore *ews_store;
 	EEwsConnection *cnc;
+	GError *local_error = NULL;
 
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
 
@@ -1384,6 +1440,10 @@ ews_append_message_sync (CamelFolder *folder,
 
 	from = CAMEL_ADDRESS (camel_mime_message_get_from (message));
 
+	if (!camel_ews_store_connected (ews_store, error)) {
+		return FALSE;
+	}
+
 	cnc = camel_ews_store_get_connection (ews_store);
 
 	if (!cnc) {
@@ -1396,7 +1456,9 @@ ews_append_message_sync (CamelFolder *folder,
 						  message,
 						  camel_message_info_flags (info),
 						  from, &itemid, &changekey,
-						  cancellable, error)) {
+						  cancellable, &local_error)) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		g_free (folder_id);
 		g_object_unref (cnc);
 		return FALSE;
@@ -1431,7 +1493,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 	CamelFolderChangeInfo *changes = NULL;
 	const gchar *dst_full_name;
 	gchar *dst_id;
-	GError *rerror = NULL;
+	GError *local_error = NULL;
 	GSList *ids = NULL, *ret_items = NULL;
 	gint i = 0;
 
@@ -1454,7 +1516,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 	if (e_ews_connection_move_items	(cnc, EWS_PRIORITY_MEDIUM,
 					 dst_id, !delete_originals,
 					 ids, &ret_items,
-					 cancellable, &rerror)) {
+					 cancellable, &local_error)) {
 		camel_service_unlock (CAMEL_SERVICE (dst_ews_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 		if (delete_originals) {
@@ -1475,14 +1537,16 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 	}
 	g_free (dst_id);
 
-	if (rerror)
-		g_propagate_error (error, rerror);
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (dst_ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
 
 	g_object_unref (cnc);
 	g_slist_free (ids);
 	g_slist_free_full (ret_items, g_object_unref);
 
-	return !rerror;
+	return !local_error;
 }
 
 static gboolean
@@ -1505,26 +1569,30 @@ ews_delete_messages (CamelFolder *folder,
 	ews_store = CAMEL_EWS_STORE (parent_store);
 	deleted_head = deleted_items;
 
+	if (!camel_ews_store_connected (ews_store, error)) {
+		return FALSE;
+	}
+
 	cnc = camel_ews_store_get_connection (ews_store);
 	changes = camel_folder_change_info_new ();
 
 	if (deleted_items) {
-		GError *rerror = NULL;
+		GError *local_error = NULL;
 		EwsDeleteType delete_type;
 
 		delete_type = expunge ? EWS_HARD_DELETE : EWS_MOVE_TO_DELETED_ITEMS;
 
 		camel_service_lock (CAMEL_SERVICE (ews_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		status = e_ews_connection_delete_items (cnc, EWS_PRIORITY_MEDIUM, deleted_items, delete_type,
-							EWS_SEND_TO_NONE, FALSE, cancellable, &rerror);
+							EWS_SEND_TO_NONE, FALSE, cancellable, &local_error);
 		camel_service_unlock (CAMEL_SERVICE (ews_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-		if (!status && rerror->code == EWS_CONNECTION_ERROR_ITEMNOTFOUND) {
+		if (!status && local_error->code == EWS_CONNECTION_ERROR_ITEMNOTFOUND) {
 			/* If delete failed due to the item not found, ignore the error,
 			 * trigger folder info refresh and then go on to clear the
 			 * cache of the deleted items anyway. */
-			g_clear_error (&rerror);
-			status = ews_refresh_info_sync (folder, cancellable, &rerror);
+			g_clear_error (&local_error);
+			status = ews_refresh_info_sync (folder, cancellable, &local_error);
 		}
 
 		if (status) {
@@ -1539,8 +1607,10 @@ ews_delete_messages (CamelFolder *folder,
 			}
 		}
 
-		if (rerror)
-			g_propagate_error (error, rerror);
+		if (local_error) {
+			camel_ews_store_maybe_disconnect (ews_store, local_error);
+			g_propagate_error (error, local_error);
+		}
 
 		camel_folder_changed (folder, changes);
 
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 25f1163..2dfa5ab 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -334,21 +334,19 @@ ews_disconnect_sync (CamelService *service,
 	CamelEwsStore *ews_store = (CamelEwsStore *) service;
 	CamelServiceClass *service_class;
 
-	service_class = CAMEL_SERVICE_CLASS (camel_ews_store_parent_class);
-	if (!service_class->disconnect_sync (service, clean, cancellable, error))
-		return FALSE;
-
 	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	/* TODO cancel all operations in the connection */
 	if (ews_store->priv->cnc) {
+		e_ews_connection_forget_password (ews_store->priv->cnc);
 		g_object_unref (ews_store->priv->cnc);
 		ews_store->priv->cnc = NULL;
 	}
 
 	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	return TRUE;
+	service_class = CAMEL_SERVICE_CLASS (camel_ews_store_parent_class);
+	return service_class->disconnect_sync (service, clean, cancellable, error);
 }
 
 typedef struct {
@@ -440,8 +438,9 @@ ews_authenticate_sync (CamelService *service,
 			ews_store, sync_state, includes_last_folder,
 			folders_created, folders_updated, folders_deleted);
 	} else {
+		g_free (sync_state);
+
 		/* Make sure we're not leaking anything. */
-		g_warn_if_fail (sync_state == NULL);
 		g_warn_if_fail (folders_created == NULL);
 		g_warn_if_fail (folders_updated == NULL);
 		g_warn_if_fail (folders_deleted == NULL);
@@ -485,9 +484,11 @@ ews_authenticate_sync (CamelService *service,
 		result = CAMEL_AUTHENTICATION_ACCEPTED;
 	} else if (g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) {
 		g_clear_error (&local_error);
+		e_ews_connection_forget_password (priv->cnc);
 		result = CAMEL_AUTHENTICATION_REJECTED;
 	} else {
 		g_propagate_error (error, local_error);
+		e_ews_connection_forget_password (priv->cnc);
 		result = CAMEL_AUTHENTICATION_ERROR;
 	}
 
@@ -626,6 +627,8 @@ ews_folder_hierarchy_ready_cb (GObject *obj,
 	if (error != NULL) {
 		g_warning ("Unable to fetch the folder hierarchy: %s :%d \n", error->message, error->code);
 
+		camel_ews_store_maybe_disconnect (ews_store, error);
+
 		g_mutex_lock (priv->get_finfo_lock);
 		ews_store->priv->last_refresh_time -= FINFO_REFRESH_INTERVAL;
 		g_mutex_unlock (priv->get_finfo_lock);
@@ -678,6 +681,7 @@ ews_get_folder_info_sync (CamelStore *store,
 	GSList *folders_created = NULL, *folders_updated = NULL;
 	GSList *folders_deleted = NULL;
 	gboolean includes_last_folder;
+	GError *local_error = NULL;
 
 	ews_store = (CamelEwsStore *) store;
 	priv = ews_store->priv;
@@ -707,13 +711,16 @@ ews_get_folder_info_sync (CamelStore *store,
 	if (!e_ews_connection_sync_folder_hierarchy (ews_store->priv->cnc, EWS_PRIORITY_MEDIUM,
 						    &sync_state, &includes_last_folder,
 						    &folders_created, &folders_updated,
-						    &folders_deleted, cancellable, error)) {
-		if (error)
+						    &folders_deleted, cancellable, &local_error)) {
+		if (local_error)
 			g_warning ("Unable to fetch the folder hierarchy: %s :%d \n",
-				   (*error)->message, (*error)->code);
+				   local_error->message, local_error->code);
 		else
 			g_warning ("Unable to fetch the folder hierarchy.\n");
 
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+
 		g_mutex_unlock (priv->get_finfo_lock);
 		return NULL;
 	}
@@ -739,6 +746,7 @@ ews_create_folder_sync (CamelStore *store,
 	gchar *full_name;
 	EwsFolderId *folder_id;
 	CamelFolderInfo *fi = NULL;
+	GError *local_error = NULL;
 
 	/* Get Parent folder ID */
 	if (parent_name && parent_name[0]) {
@@ -751,9 +759,7 @@ ews_create_folder_sync (CamelStore *store,
 		}
 	}
 
-	if (!ews_store->priv->cnc) {
-		g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			     _("Cant perform actions on the folder while in offline mode"));
+	if (!camel_ews_store_connected (ews_store, error)) {
 		if (fid) g_free (fid);
 		return NULL;
 	}
@@ -762,7 +768,9 @@ ews_create_folder_sync (CamelStore *store,
 	if (!e_ews_connection_create_folder (ews_store->priv->cnc,
 					     EWS_PRIORITY_MEDIUM, fid,
 					     FALSE, folder_name, &folder_id,
-					     cancellable, error)) {
+					     cancellable, &local_error)) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		g_free (fid);
 		return NULL;
 	}
@@ -798,6 +806,7 @@ ews_delete_folder_sync (CamelStore *store,
 	CamelEwsStoreSummary *ews_summary = ews_store->summary;
 	gchar *fid;
 	CamelFolderInfo *fi = NULL;
+	GError *local_error = NULL;
 
 	fid = camel_ews_store_summary_get_folder_id_from_name (ews_summary,
 							       folder_name);
@@ -807,9 +816,7 @@ ews_delete_folder_sync (CamelStore *store,
 		return FALSE;
 	}
 
-	if (!ews_store->priv->cnc) {
-		g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			     _("Cant perform actions on the folder while in offline mode"));
+	if (!camel_ews_store_connected (ews_store, error)) {
 		g_free (fid);
 		return FALSE;
 	}
@@ -817,7 +824,9 @@ ews_delete_folder_sync (CamelStore *store,
 	if (!e_ews_connection_delete_folder (ews_store->priv->cnc,
 					     EWS_PRIORITY_MEDIUM,
 					     fid, FALSE, "HardDelete",
-					     cancellable, error)) {
+					     cancellable, &local_error)) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		g_free (fid);
 		return FALSE;
 	}
@@ -873,13 +882,12 @@ ews_rename_folder_sync (CamelStore *store,
 	gchar *fid;
 	gchar *changekey;
 	gboolean res = FALSE;
+	GError *local_error = NULL;
 
 	if (!strcmp (old_name, new_name))
 		return TRUE;
 
-	if (!ews_store->priv->cnc) {
-		g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			     _("Cant perform actions on the folder while in offline mode"));
+	if (!camel_ews_store_connected (ews_store, error)) {
 		return FALSE;
 	}
 
@@ -946,7 +954,7 @@ ews_rename_folder_sync (CamelStore *store,
 		rename_data->change_key = changekey;
 
 		if (!e_ews_connection_update_folder (ews_store->priv->cnc, EWS_PRIORITY_MEDIUM,
-						     rename_folder_cb, rename_data, cancellable, error)) {
+						     rename_folder_cb, rename_data, cancellable, &local_error)) {
 			g_free (rename_data);
 			goto out;
 		}
@@ -972,7 +980,7 @@ ews_rename_folder_sync (CamelStore *store,
 			}
 		}
 		if (!e_ews_connection_move_folder (ews_store->priv->cnc, EWS_PRIORITY_MEDIUM,
-						   pfid, fid, cancellable, error)) {
+						   pfid, fid, cancellable, &local_error)) {
 			g_free (pfid);
 			goto out;
 		}
@@ -982,6 +990,11 @@ ews_rename_folder_sync (CamelStore *store,
 
 	res = TRUE;
  out:
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
+
 	g_free (changekey);
 	g_free (fid);
 	return res;
@@ -1091,6 +1104,27 @@ camel_ews_store_connected (CamelEwsStore *ews_store,
 	return TRUE;
 }
 
+void
+camel_ews_store_maybe_disconnect (CamelEwsStore *store,
+				  const GError *error)
+{
+	CamelService *service;
+
+	g_return_if_fail (store != NULL);
+
+	if (!error)
+		return;
+
+	service = CAMEL_SERVICE (store);
+
+	if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
+		return;
+
+	if (g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_NORESPONSE) ||
+	    g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED))
+		camel_service_disconnect_sync (service, FALSE, NULL);
+}
+
 static void
 ews_store_dispose (GObject *object)
 {
diff --git a/src/camel/camel-ews-store.h b/src/camel/camel-ews-store.h
index a159325..9a83704 100644
--- a/src/camel/camel-ews-store.h
+++ b/src/camel/camel-ews-store.h
@@ -75,6 +75,9 @@ EEwsConnection *
 
 gboolean	camel_ews_store_connected	(CamelEwsStore *store,
 						 GError **error);
+void		camel_ews_store_maybe_disconnect
+						(CamelEwsStore *store,
+						 const GError *error);
 
 G_END_DECLS
 
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 83e5e72..9a673a5 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -973,10 +973,7 @@ e_ews_connection_dispose (GObject *object)
 		priv->username = NULL;
 	}
 
-	if (priv->password) {
-		g_free (priv->password);
-		priv->password = NULL;
-	}
+	e_ews_connection_forget_password (cnc);
 
 	if (priv->email) {
 		g_free (priv->email);
@@ -1094,8 +1091,7 @@ ews_connection_authenticate (SoupSession *sess,
 	EEwsConnection *cnc = data;
 
 	if (retrying) {
-		g_free (cnc->priv->password);
-		cnc->priv->password = NULL;
+		e_ews_connection_forget_password (cnc);
 	}
 
 	if (cnc->priv->password) {
@@ -1139,7 +1135,7 @@ e_ews_connection_authenticate (EEwsConnection *cnc,
 		cnc->priv->username = g_strdup (user);
 	}
 
-	g_free (cnc->priv->password);
+	e_ews_connection_forget_password (cnc);
 	cnc->priv->password = g_strdup (passwd);
 
 	soup_auth_authenticate (auth, cnc->priv->username,
@@ -1262,6 +1258,19 @@ e_ews_connection_new (const gchar *uri,
 
 }
 
+void
+e_ews_connection_forget_password (EEwsConnection *cnc)
+{
+	g_return_if_fail (cnc != NULL);
+
+	if (cnc->priv->password && *cnc->priv->password) {
+		memset (cnc->priv->password, 0, strlen (cnc->priv->password));
+	}
+
+	g_free (cnc->priv->password);
+	cnc->priv->password = NULL;
+}
+
 static xmlDoc *
 e_ews_autodiscover_ws_xml (const gchar *email)
 {
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index aa266ae..f47b460 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -187,6 +187,9 @@ EEwsConnection *e_ews_connection_new		(const gchar *uri,
 						 GCallback authenticate_cb,
 						 gpointer authenticate_ctx,
 						 GError **error);
+void		e_ews_connection_forget_password
+						(EEwsConnection *cnc);
+
 EEwsConnection *e_ews_connection_find		(const gchar *uri,
 						 const gchar *username);
 void		e_ews_connection_authenticate	(EEwsConnection *cnc,



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