summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2018-12-12 11:37:07 +0100
committerMilan Crha <mcrha@redhat.com>2018-12-12 11:37:07 +0100
commitcd03f3f015df0e1306aa40076843846e3dd8140b (patch)
tree5886005b099fe5103a3cd08ee814407099fd0ac4
parentd39396e9a38e3830c2292a61f7eb276342de2849 (diff)
downloadevolution-data-server-cd03f3f015df0e1306aa40076843846e3dd8140b.tar.gz
I#68 - WebDAV registry backend Refresh can remove existing sources
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/68
-rw-r--r--src/libebackend/e-backend.c15
-rw-r--r--src/libebackend/e-collection-backend.c50
-rw-r--r--src/libebackend/e-webdav-collection-backend.c5
-rw-r--r--src/libedataserver/e-webdav-discover.c9
4 files changed, 65 insertions, 14 deletions
diff --git a/src/libebackend/e-backend.c b/src/libebackend/e-backend.c
index 8e1cc4874..1c09797bd 100644
--- a/src/libebackend/e-backend.c
+++ b/src/libebackend/e-backend.c
@@ -69,6 +69,7 @@ struct _EBackendPrivate {
GMutex network_monitor_cancellable_lock;
GCancellable *network_monitor_cancellable;
+ GMutex authenticate_lock; /* To not run multiple authenticate requests simultaneously */
GMutex authenticate_cancellable_lock;
GCancellable *authenticate_cancellable;
};
@@ -285,6 +286,7 @@ e_backend_authenticate_sync (EBackend *backend,
GError **error)
{
EBackendClass *class;
+ ESourceAuthenticationResult res;
g_return_val_if_fail (E_IS_BACKEND (backend), E_SOURCE_AUTHENTICATION_ERROR);
g_return_val_if_fail (credentials != NULL, E_SOURCE_AUTHENTICATION_ERROR);
@@ -293,7 +295,16 @@ e_backend_authenticate_sync (EBackend *backend,
g_return_val_if_fail (class != NULL, E_SOURCE_AUTHENTICATION_ERROR);
g_return_val_if_fail (class->authenticate_sync != NULL, E_SOURCE_AUTHENTICATION_ERROR);
- return class->authenticate_sync (backend, credentials, out_certificate_pem, out_certificate_errors, cancellable, error);
+ g_mutex_lock (&backend->priv->authenticate_lock);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ res = E_SOURCE_AUTHENTICATION_ERROR;
+ else
+ res = class->authenticate_sync (backend, credentials, out_certificate_pem, out_certificate_errors, cancellable, error);
+
+ g_mutex_unlock (&backend->priv->authenticate_lock);
+
+ return res;
}
typedef struct _AuthenticateThreadData {
@@ -625,6 +636,7 @@ backend_finalize (GObject *object)
g_mutex_clear (&priv->property_lock);
g_mutex_clear (&priv->update_online_state_lock);
g_mutex_clear (&priv->network_monitor_cancellable_lock);
+ g_mutex_clear (&priv->authenticate_lock);
g_mutex_clear (&priv->authenticate_cancellable_lock);
/* Chain up to parent's finalize() method. */
@@ -802,6 +814,7 @@ e_backend_init (EBackend *backend)
g_mutex_init (&backend->priv->property_lock);
g_mutex_init (&backend->priv->update_online_state_lock);
g_mutex_init (&backend->priv->network_monitor_cancellable_lock);
+ g_mutex_init (&backend->priv->authenticate_lock);
g_mutex_init (&backend->priv->authenticate_cancellable_lock);
backend->priv->authenticate_cancellable = NULL;
diff --git a/src/libebackend/e-collection-backend.c b/src/libebackend/e-collection-backend.c
index c92925ea5..5c1f20801 100644
--- a/src/libebackend/e-collection-backend.c
+++ b/src/libebackend/e-collection-backend.c
@@ -142,6 +142,38 @@ collection_backend_children_list (ECollectionBackend *backend)
return list;
}
+static ESource *
+collection_backend_ref_child_source (ECollectionBackend *backend,
+ const gchar *resource_id)
+{
+ ESource *source = NULL;
+ GHashTableIter iter;
+ gpointer key;
+
+ g_mutex_lock (&backend->priv->children_lock);
+
+ g_hash_table_iter_init (&iter, backend->priv->children);
+
+ while (!source && g_hash_table_iter_next (&iter, &key, NULL)) {
+ ESource *candidate = key;
+ gchar *candidate_resource_id;
+
+ if (!candidate)
+ continue;
+
+ candidate_resource_id = e_collection_backend_dup_resource_id (backend, candidate);
+ if (g_strcmp0 (candidate_resource_id, resource_id) == 0) {
+ source = g_object_ref (candidate);
+ }
+
+ g_free (candidate_resource_id);
+ }
+
+ g_mutex_unlock (&backend->priv->children_lock);
+
+ return source;
+}
+
static GFile *
collection_backend_new_user_file (ECollectionBackend *backend)
{
@@ -338,15 +370,19 @@ collection_backend_claim_resource (ECollectionBackend *backend,
g_object_ref (source);
g_hash_table_remove (unclaimed_resources, resource_id);
} else {
- GFile *file = collection_backend_new_user_file (backend);
- source = collection_backend_new_source (backend, file, error);
- g_object_unref (file);
+ source = collection_backend_ref_child_source (backend, resource_id);
- if (source) {
- if (!backend->priv->new_sources)
- backend->priv->new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ if (!source) {
+ GFile *file = collection_backend_new_user_file (backend);
+ source = collection_backend_new_source (backend, file, error);
+ g_object_unref (file);
- g_hash_table_insert (backend->priv->new_sources, e_source_dup_uid (source), NULL);
+ if (source) {
+ if (!backend->priv->new_sources)
+ backend->priv->new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ g_hash_table_insert (backend->priv->new_sources, e_source_dup_uid (source), NULL);
+ }
}
}
diff --git a/src/libebackend/e-webdav-collection-backend.c b/src/libebackend/e-webdav-collection-backend.c
index bcf00ec8e..76835cb38 100644
--- a/src/libebackend/e-webdav-collection-backend.c
+++ b/src/libebackend/e-webdav-collection-backend.c
@@ -148,7 +148,6 @@ webdav_collection_add_found_source (ECollectionBackend *collection,
g_warn_if_fail (source != NULL);
} else {
source = e_source_registry_server_ref_source (server, source_uid);
- g_warn_if_fail (source != NULL);
g_hash_table_remove (known_sources, identity);
}
@@ -508,6 +507,7 @@ e_webdav_collection_backend_discover_sync (EWebDAVCollectionBackend *webdav_back
server = e_collection_backend_ref_server (collection);
if (e_source_collection_get_calendar_enabled (collection_extension) && calendar_url &&
+ !g_cancellable_is_cancelled (cancellable) &&
e_webdav_discover_sources_full_sync (source, calendar_url,
E_WEBDAV_DISCOVER_SUPPORTS_EVENTS | E_WEBDAV_DISCOVER_SUPPORTS_MEMOS | E_WEBDAV_DISCOVER_SUPPORTS_TASKS | E_WEBDAV_DISCOVER_SUPPORTS_CALENDAR_AUTO_SCHEDULE,
credentials, (EWebDAVDiscoverRefSourceFunc) e_source_registry_server_ref_source, server,
@@ -526,6 +526,7 @@ e_webdav_collection_backend_discover_sync (EWebDAVCollectionBackend *webdav_back
}
if (!local_error && e_source_collection_get_contacts_enabled (collection_extension) && contacts_url &&
+ !g_cancellable_is_cancelled (cancellable) &&
e_webdav_discover_sources_full_sync (source, contacts_url, E_WEBDAV_DISCOVER_SUPPORTS_CONTACTS,
credentials, (EWebDAVDiscoverRefSourceFunc) e_source_registry_server_ref_source, server,
out_certificate_pem, out_certificate_errors, &discovered_sources, NULL, cancellable, &local_error)) {
@@ -540,7 +541,7 @@ e_webdav_collection_backend_discover_sync (EWebDAVCollectionBackend *webdav_back
any_success = TRUE;
}
- if (any_success && server) {
+ if (any_success && server && !g_cancellable_is_cancelled (cancellable)) {
RemoveSourcesData rsd;
rsd.server = server;
diff --git a/src/libedataserver/e-webdav-discover.c b/src/libedataserver/e-webdav-discover.c
index 986cd49c2..a8efac8b5 100644
--- a/src/libedataserver/e-webdav-discover.c
+++ b/src/libedataserver/e-webdav-discover.c
@@ -110,7 +110,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
length = xmlXPathNodeSetGetLength (xpath_obj->nodesetval);
- for (ii = 0; ii < length; ii++) {
+ for (ii = 0; ii < length && !g_cancellable_is_cancelled (wdd->cancellable); ii++) {
gchar *home_set_href;
full_href = NULL;
@@ -145,7 +145,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
length = xmlXPathNodeSetGetLength (xpath_obj->nodesetval);
- for (ii = 0; ii < length; ii++) {
+ for (ii = 0; ii < length && !g_cancellable_is_cancelled (wdd->cancellable); ii++) {
gchar *home_set_href, *full_href = NULL;
home_set_href = e_xml_xpath_eval_as_string (xpath_ctx, "%s/C:calendar-home-set/D:href[%d]", xpath_prop_prefix, ii + 1);
@@ -204,7 +204,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
}
principal_href = e_xml_xpath_eval_as_string (xpath_ctx, "%s/D:current-user-principal/D:href", xpath_prop_prefix);
- if (principal_href && *principal_href) {
+ if (principal_href && *principal_href && !g_cancellable_is_cancelled (wdd->cancellable)) {
full_href = e_webdav_session_ensure_full_uri (webdav, request_uri, principal_href);
if (full_href && *full_href)
@@ -219,7 +219,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
g_free (principal_href);
principal_href = e_xml_xpath_eval_as_string (xpath_ctx, "%s/D:principal-URL/D:href", xpath_prop_prefix);
- if (principal_href && *principal_href) {
+ if (principal_href && *principal_href && !g_cancellable_is_cancelled (wdd->cancellable)) {
full_href = e_webdav_session_ensure_full_uri (webdav, request_uri, principal_href);
if (full_href && *full_href)
@@ -238,6 +238,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
GSList *resources = NULL;
if (!g_hash_table_contains (wdd->covered_hrefs, href) &&
+ !g_cancellable_is_cancelled (wdd->cancellable) &&
e_webdav_session_list_sync (webdav, href, E_WEBDAV_DEPTH_THIS,
E_WEBDAV_LIST_SUPPORTS | E_WEBDAV_LIST_DISPLAY_NAME | E_WEBDAV_LIST_DESCRIPTION | E_WEBDAV_LIST_COLOR,
&resources, wdd->cancellable, wdd->error)) {