[evolution-ews] I#90 - Handle share folder invitation mails
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] I#90 - Handle share folder invitation mails
- Date: Tue, 29 Sep 2020 12:10:21 +0000 (UTC)
commit a2d3cdf803cde27069ccffc6d19a585543c14ff1
Author: Milan Crha <mcrha redhat com>
Date: Tue Sep 29 14:07:48 2020 +0200
I#90 - Handle share folder invitation mails
Closes https://gitlab.gnome.org/GNOME/evolution-ews/-/issues/90
src/EWS/common/e-ews-connection.c | 167 ++++++++++++++
src/EWS/common/e-ews-connection.h | 23 ++
src/EWS/evolution/CMakeLists.txt | 8 +
src/EWS/evolution/e-ews-subscribe-foreign-folder.c | 242 ++++++++++++---------
src/EWS/evolution/e-ews-subscribe-foreign-folder.h | 33 ++-
.../e-mail-formatter-ews-sharing-metadata.c | 223 +++++++++++++++++++
.../e-mail-formatter-ews-sharing-metadata.h | 18 ++
.../evolution/e-mail-parser-ews-multipart-mixed.c | 103 +++++++++
.../evolution/e-mail-parser-ews-multipart-mixed.h | 18 ++
.../evolution/e-mail-parser-ews-sharing-metadata.c | 123 +++++++++++
.../evolution/e-mail-parser-ews-sharing-metadata.h | 23 ++
.../evolution/e-mail-part-ews-sharing-metadata.c | 233 ++++++++++++++++++++
.../evolution/e-mail-part-ews-sharing-metadata.h | 54 +++++
src/EWS/evolution/module-ews-configuration.c | 8 +
.../evolution/module-ews-configuration.error.xml | 10 +
15 files changed, 1178 insertions(+), 108 deletions(-)
---
diff --git a/src/EWS/common/e-ews-connection.c b/src/EWS/common/e-ews-connection.c
index 1d318068..464e2ad7 100644
--- a/src/EWS/common/e-ews-connection.c
+++ b/src/EWS/common/e-ews-connection.c
@@ -11771,3 +11771,170 @@ e_ews_connection_get_user_configuration_sync (EEwsConnection *cnc,
return success;
}
+
+static void
+convert_id_response_cb (ESoapResponse *response,
+ GSimpleAsyncResult *simple)
+{
+ EwsAsyncData *async_data;
+ ESoapParameter *param;
+ GError *error = NULL;
+
+ async_data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &error);
+
+ if (param) {
+ param = e_soap_parameter_get_first_child_by_name (param, "ConvertIdResponseMessage");
+ if (!param) {
+ g_set_error (&error,
+ SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
+ "Missing <%s> in SOAP response", "ConvertIdResponseMessage");
+ }
+ }
+
+ if (param) {
+ param = e_soap_parameter_get_first_child_by_name (param, "AlternateId");
+ if (!param) {
+ g_set_error (&error,
+ SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
+ "Missing <%s> in SOAP response", "AlternateId");
+ }
+ }
+
+ /* Sanity check */
+ g_return_if_fail (
+ (param != NULL && error == NULL) ||
+ (param == NULL && error != NULL));
+
+ if (error != NULL) {
+ g_simple_async_result_take_error (simple, error);
+ return;
+ }
+
+ async_data->custom_data = e_soap_parameter_get_property (param, "Id");
+}
+
+void
+e_ews_connection_convert_id (EEwsConnection *cnc,
+ gint pri,
+ const gchar *email,
+ const gchar *folder_id,
+ const gchar *from_format,
+ const gchar *to_format,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ESoapMessage *msg;
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ g_return_if_fail (cnc != NULL);
+ g_return_if_fail (cnc->priv != NULL);
+ g_return_if_fail (email != NULL);
+ g_return_if_fail (folder_id != NULL);
+ g_return_if_fail (from_format != NULL);
+ g_return_if_fail (to_format != NULL);
+
+ simple = g_simple_async_result_new (G_OBJECT (cnc), callback, user_data, e_ews_connection_convert_id);
+ async_data = g_slice_new0 (EwsAsyncData);
+ g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
+
+ /* EWS server version earlier than 2007 SP1 doesn't support it. */
+ if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2007_SP1)) {
+ g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR, "%s", _("Requires at least
Microsoft Exchange 2007 SP1 server"));
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ msg = e_ews_message_new_with_header (
+ cnc->priv->settings,
+ cnc->priv->uri,
+ cnc->priv->impersonate_user,
+ "ConvertId",
+ "DestinationFormat",
+ to_format,
+ cnc->priv->version,
+ E_EWS_EXCHANGE_2007_SP1,
+ FALSE,
+ TRUE);
+
+ e_soap_message_start_element (msg, "SourceIds", "messages", NULL);
+ e_soap_message_start_element (msg, "AlternateId", NULL, NULL);
+
+ e_soap_message_add_attribute (msg, "Id", folder_id, NULL, NULL);
+ e_soap_message_add_attribute (msg, "Format", from_format, NULL, NULL);
+ e_soap_message_add_attribute (msg, "Mailbox", email, NULL, NULL);
+
+ e_soap_message_end_element (msg); /* AlternateId */
+ e_soap_message_end_element (msg); /* SourceIds */
+
+ e_ews_message_write_footer (msg);
+
+ e_ews_connection_queue_request (cnc, msg, convert_id_response_cb, pri, cancellable, simple);
+
+ g_object_unref (simple);
+}
+
+gboolean
+e_ews_connection_convert_id_finish (EEwsConnection *cnc,
+ GAsyncResult *result,
+ gchar **out_converted_id,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ g_return_val_if_fail (cnc != NULL, FALSE);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (result, G_OBJECT (cnc), e_ews_connection_convert_id),
+ FALSE);
+ g_return_val_if_fail (out_converted_id != NULL, FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ if (!async_data->custom_data)
+ return FALSE;
+
+ *out_converted_id = async_data->custom_data;
+ async_data->custom_data = NULL;
+
+ return TRUE;
+}
+
+gboolean
+e_ews_connection_convert_id_sync (EEwsConnection *cnc,
+ gint pri,
+ const gchar *email,
+ const gchar *folder_id,
+ const gchar *from_format,
+ const gchar *to_format,
+ gchar **out_converted_id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EAsyncClosure *closure;
+ GAsyncResult *result;
+ gboolean success;
+
+ g_return_val_if_fail (cnc != NULL, FALSE);
+
+ closure = e_async_closure_new ();
+
+ e_ews_connection_convert_id (
+ cnc, pri, email, folder_id, from_format, to_format, cancellable, e_async_closure_callback,
closure);
+
+ result = e_async_closure_wait (closure);
+
+ success = e_ews_connection_convert_id_finish (cnc, result, out_converted_id, error);
+
+ e_async_closure_free (closure);
+
+ return success;
+}
diff --git a/src/EWS/common/e-ews-connection.h b/src/EWS/common/e-ews-connection.h
index 3ad44bea..3e2b2785 100644
--- a/src/EWS/common/e-ews-connection.h
+++ b/src/EWS/common/e-ews-connection.h
@@ -1398,6 +1398,29 @@ gboolean e_ews_connection_get_user_configuration_sync
gchar **out_properties,
GCancellable *cancellable,
GError **error);
+void e_ews_connection_convert_id (EEwsConnection *cnc,
+ gint pri,
+ const gchar *email,
+ const gchar *folder_id,
+ const gchar *from_format,
+ const gchar *to_format,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_ews_connection_convert_id_finish
+ (EEwsConnection *cnc,
+ GAsyncResult *result,
+ gchar **out_converted_id,
+ GError **error);
+gboolean e_ews_connection_convert_id_sync(EEwsConnection *cnc,
+ gint pri,
+ const gchar *email,
+ const gchar *folder_id,
+ const gchar *from_format,
+ const gchar *to_format,
+ gchar **out_converted_id,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/EWS/evolution/CMakeLists.txt b/src/EWS/evolution/CMakeLists.txt
index 76779bb9..70f65bde 100644
--- a/src/EWS/evolution/CMakeLists.txt
+++ b/src/EWS/evolution/CMakeLists.txt
@@ -27,6 +27,14 @@ set(sources
e-mail-config-ews-offline-options.h
e-mail-config-ews-ooo-page.c
e-mail-config-ews-ooo-page.h
+ e-mail-formatter-ews-sharing-metadata.c
+ e-mail-formatter-ews-sharing-metadata.h
+ e-mail-parser-ews-multipart-mixed.c
+ e-mail-parser-ews-multipart-mixed.h
+ e-mail-parser-ews-sharing-metadata.c
+ e-mail-parser-ews-sharing-metadata.h
+ e-mail-part-ews-sharing-metadata.c
+ e-mail-part-ews-sharing-metadata.h
e-ews-config-lookup.c
e-ews-config-lookup.h
e-ews-config-ui-extension.c
diff --git a/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
b/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
index 5204d54e..09c3ae13 100644
--- a/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
+++ b/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
@@ -271,62 +271,11 @@ check_foreign_folder_thread (GObject *with_object,
cffd->user_displayname = cffd->email;
cffd->email = g_strdup (cffd->direct_email);
} else {
- GSList *mailboxes = NULL;
- EwsMailbox *mailbox = NULL;
- gboolean includes_last_item = FALSE;
-
- if (!e_ews_connection_resolve_names_sync (conn, G_PRIORITY_DEFAULT,
- cffd->email, EWS_SEARCH_AD, NULL, FALSE,
- &mailboxes, NULL, &includes_last_item,
- cancellable, &local_error)) {
- if (g_error_matches (local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NAMERESOLUTIONNORESULTS) ||
- g_error_matches (local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NAMERESOLUTIONNOMAILBOX)) {
- g_clear_error (&local_error);
- mailboxes = NULL;
- } else {
- if (local_error)
- g_propagate_error (perror, local_error);
- g_object_unref (conn);
- return;
- }
- }
-
- if (mailboxes) {
- /* is there only one result? */
- if (!mailboxes->next) {
- mailbox = mailboxes->data;
- } else {
- GSList *iter;
-
- for (iter = mailboxes; iter; iter = iter->next) {
- EwsMailbox *mb = iter->data;
-
- if (!mb)
- continue;
-
- if (mb->name && g_utf8_collate (mb->name, cffd->email) == 0) {
- mailbox = mb;
- break;
- }
- }
- }
-
- if (mailbox) {
- g_free (cffd->user_displayname);
- cffd->user_displayname = g_strdup (mailbox->name);
- g_free (cffd->email);
- cffd->email = g_strdup (mailbox->email);
- }
+ gchar *display_name = NULL, *email_address = NULL;
- g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
-
- if (!mailbox) {
- g_set_error (
- perror, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND,
- _("User name “%s” is ambiguous, specify it more precisely, please"),
cffd->email);
- g_object_unref (conn);
- return;
- }
+ if (!e_ews_subscribe_foreign_folder_resolve_name_sync (conn, cffd->email, &display_name,
&email_address, cancellable, perror)) {
+ g_object_unref (conn);
+ return;
}
}
@@ -418,14 +367,6 @@ check_foreign_folder_idle (GObject *with_object,
GError **perror)
{
struct EEwsCheckForeignFolderData *cffd = user_data;
- gchar *folder_name;
- const gchar *base_username, *base_foldername;
- CamelSettings *settings;
- CamelEwsSettings *ews_settings;
- CamelEwsStore *ews_store;
- ESourceRegistry *registry = NULL;
- CamelSession *session;
- EEwsFolderType folder_type;
g_return_if_fail (with_object != NULL);
g_return_if_fail (CAMEL_IS_EWS_STORE (with_object));
@@ -435,51 +376,13 @@ check_foreign_folder_idle (GObject *with_object,
if (!cffd->folder)
return;
- folder_type = e_ews_folder_get_folder_type (cffd->folder);
- base_username = cffd->user_displayname ? cffd->user_displayname : cffd->email;
- base_foldername = e_ews_folder_get_name (cffd->folder) ? e_ews_folder_get_name (cffd->folder) :
cffd->orig_foldername;
-
- /* Translators: This is used to name foreign folder.
- * The first '%s' is replaced with user name to whom the folder belongs,
- * the second '%s' is replaced with folder name.
- * Example result: "John Smith — Calendar"
- */
- folder_name = g_strdup_printf (C_("ForeignFolder", "%s — %s"), base_username, base_foldername);
- if (folder_type != E_EWS_FOLDER_TYPE_MAILBOX)
- e_ews_folder_set_name (cffd->folder, folder_name);
-
- ews_store = CAMEL_EWS_STORE (with_object);
- settings = camel_service_ref_settings (CAMEL_SERVICE (ews_store));
- ews_settings = CAMEL_EWS_SETTINGS (settings);
- session = camel_service_ref_session (CAMEL_SERVICE (ews_store));
- if (E_IS_MAIL_SESSION (session))
- registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
-
- if ((folder_type == E_EWS_FOLDER_TYPE_MAILBOX &&
- !add_foreign_folder_to_camel (ews_store,
- cffd->email,
- cffd->folder,
- cffd->include_subfolders,
- base_username,
- base_foldername,
- perror)) ||
- (folder_type != E_EWS_FOLDER_TYPE_MAILBOX && !e_ews_folder_utils_add_as_esource (registry,
- camel_ews_settings_get_hosturl (ews_settings),
- camel_network_settings_get_user (CAMEL_NETWORK_SETTINGS (ews_settings)),
- cffd->folder,
- (cffd->include_subfolders ? E_EWS_ESOURCE_FLAG_INCLUDE_SUBFOLDERS : 0) |
E_EWS_ESOURCE_FLAG_OFFLINE_SYNC,
- 0,
- cancellable,
- perror))
- ) {
+ if (!e_ews_subscrive_foreign_folder_subscribe_sync (CAMEL_EWS_STORE (with_object),
+ cffd->folder, cffd->user_displayname, cffd->email, cffd->orig_foldername,
+ cffd->include_subfolders, cancellable, perror)) {
/* to not destroy the dialog on error */
g_object_unref (cffd->folder);
cffd->folder = NULL;
}
-
- g_free (folder_name);
- g_object_unref (session);
- g_object_unref (settings);
}
static gpointer
@@ -875,3 +778,134 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
gtk_widget_show_all (content);
gtk_widget_show (GTK_WIDGET (dialog));
}
+
+gboolean
+e_ews_subscribe_foreign_folder_resolve_name_sync (EEwsConnection *cnc,
+ const gchar *name,
+ gchar **out_display_name,
+ gchar **out_email_address,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GSList *mailboxes = NULL;
+ EwsMailbox *mailbox = NULL;
+ gboolean includes_last_item = FALSE;
+ GError *local_error = NULL;
+
+ if (!e_ews_connection_resolve_names_sync (cnc, G_PRIORITY_DEFAULT,
+ name, EWS_SEARCH_AD, NULL, FALSE,
+ &mailboxes, NULL, &includes_last_item,
+ cancellable, &local_error)) {
+ if (g_error_matches (local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NAMERESOLUTIONNORESULTS) ||
+ g_error_matches (local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NAMERESOLUTIONNOMAILBOX)) {
+ g_clear_error (&local_error);
+ mailboxes = NULL;
+ } else {
+ if (local_error)
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+ }
+
+ if (mailboxes) {
+ /* is there only one result? */
+ if (!mailboxes->next) {
+ mailbox = mailboxes->data;
+ } else {
+ GSList *iter;
+
+ for (iter = mailboxes; iter; iter = iter->next) {
+ EwsMailbox *mb = iter->data;
+
+ if (!mb)
+ continue;
+
+ if (mb->name && g_utf8_collate (mb->name, name) == 0) {
+ mailbox = mb;
+ break;
+ }
+ }
+ }
+
+ if (mailbox) {
+ if (out_display_name)
+ *out_display_name = g_strdup (mailbox->name);
+
+ if (out_email_address)
+ *out_email_address = g_strdup (mailbox->email);
+ }
+
+ g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
+
+ if (!mailbox) {
+ g_set_error (
+ error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND,
+ _("User name “%s” is ambiguous, specify it more precisely, please"), name);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+e_ews_subscrive_foreign_folder_subscribe_sync (CamelEwsStore *ews_store,
+ EEwsFolder *folder,
+ const gchar *user_display_name,
+ const gchar *user_email,
+ const gchar *fallback_folder_name,
+ gboolean include_subfolders,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gchar *folder_name;
+ const gchar *base_username, *base_foldername;
+ CamelSettings *settings;
+ CamelEwsSettings *ews_settings;
+ ESourceRegistry *registry = NULL;
+ CamelSession *session;
+ EEwsFolderType folder_type;
+ gboolean success;
+
+ folder_type = e_ews_folder_get_folder_type (folder);
+ base_username = user_display_name ? user_display_name : user_email;
+ base_foldername = e_ews_folder_get_name (folder) ? e_ews_folder_get_name (folder) :
fallback_folder_name;
+
+ /* Translators: This is used to name foreign folder.
+ * The first '%s' is replaced with user name to whom the folder belongs,
+ * the second '%s' is replaced with folder name.
+ * Example result: "John Smith — Calendar"
+ */
+ folder_name = g_strdup_printf (C_("ForeignFolder", "%s — %s"), base_username, base_foldername);
+ if (folder_type != E_EWS_FOLDER_TYPE_MAILBOX)
+ e_ews_folder_set_name (folder, folder_name);
+
+ settings = camel_service_ref_settings (CAMEL_SERVICE (ews_store));
+ ews_settings = CAMEL_EWS_SETTINGS (settings);
+ session = camel_service_ref_session (CAMEL_SERVICE (ews_store));
+ if (E_IS_MAIL_SESSION (session))
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+ success = (folder_type == E_EWS_FOLDER_TYPE_MAILBOX &&
+ !add_foreign_folder_to_camel (ews_store,
+ user_email,
+ folder,
+ include_subfolders,
+ base_username,
+ base_foldername,
+ error)) ||
+ (folder_type != E_EWS_FOLDER_TYPE_MAILBOX && !e_ews_folder_utils_add_as_esource (registry,
+ camel_ews_settings_get_hosturl (ews_settings),
+ camel_network_settings_get_user (CAMEL_NETWORK_SETTINGS (ews_settings)),
+ folder,
+ (include_subfolders ? E_EWS_ESOURCE_FLAG_INCLUDE_SUBFOLDERS : 0) |
E_EWS_ESOURCE_FLAG_OFFLINE_SYNC,
+ 0,
+ cancellable,
+ error));
+
+ g_free (folder_name);
+ g_object_unref (session);
+ g_object_unref (settings);
+
+ return success;
+}
diff --git a/src/EWS/evolution/e-ews-subscribe-foreign-folder.h
b/src/EWS/evolution/e-ews-subscribe-foreign-folder.h
index 9d3e31d7..526601da 100644
--- a/src/EWS/evolution/e-ews-subscribe-foreign-folder.h
+++ b/src/EWS/evolution/e-ews-subscribe-foreign-folder.h
@@ -9,9 +9,34 @@
#include <e-util/e-util.h>
-void e_ews_subscribe_foreign_folder (GtkWindow *parent,
- CamelSession *session,
- CamelStore *store,
- EClientCache *client_cache);
+#include "camel/camel-ews-store.h"
+#include "common/e-ews-connection.h"
+#include "common/e-ews-folder.h"
+
+G_BEGIN_DECLS
+
+void e_ews_subscribe_foreign_folder (GtkWindow *parent,
+ CamelSession *session,
+ CamelStore *store,
+ EClientCache *client_cache);
+
+gboolean e_ews_subscribe_foreign_folder_resolve_name_sync
+ (EEwsConnection *cnc,
+ const gchar *name,
+ gchar **out_display_name,
+ gchar **out_email_address,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean e_ews_subscrive_foreign_folder_subscribe_sync
+ (CamelEwsStore *ews_store,
+ EEwsFolder *folder,
+ const gchar *user_display_name,
+ const gchar *user_email,
+ const gchar *fallback_folder_name,
+ gboolean include_subfolders,
+ GCancellable *cancellable,
+ GError **error);
+G_END_DECLS
#endif /* E_EWS_SUBSCRIBE_FOREIGN_FOLDER_H */
diff --git a/src/EWS/evolution/e-mail-formatter-ews-sharing-metadata.c
b/src/EWS/evolution/e-mail-formatter-ews-sharing-metadata.c
new file mode 100644
index 00000000..c998030f
--- /dev/null
+++ b/src/EWS/evolution/e-mail-formatter-ews-sharing-metadata.c
@@ -0,0 +1,223 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-ews-config.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/libedataserver.h>
+#include <em-format/e-mail-formatter-extension.h>
+#include <em-format/e-mail-formatter.h>
+#include <em-format/e-mail-part-utils.h>
+
+#include "e-mail-part-ews-sharing-metadata.h"
+#include "e-mail-formatter-ews-sharing-metadata.h"
+
+typedef EMailFormatterExtension EMailFormatterEwsSharingMetadata;
+typedef EMailFormatterExtensionClass EMailFormatterEwsSharingMetadataClass;
+
+GType e_mail_formatter_ews_sharing_metadata_get_type (void);
+
+G_DEFINE_DYNAMIC_TYPE (EMailFormatterEwsSharingMetadata, e_mail_formatter_ews_sharing_metadata,
E_TYPE_MAIL_FORMATTER_EXTENSION)
+
+static const gchar *formatter_mime_types[] = {
+ "application/x-sharing-metadata-xml",
+ NULL
+};
+
+static gboolean
+emf_ews_sharing_metadata (const gchar *xml_str,
+ gchar **out_datatype,
+ gchar **out_initiator_name,
+ gchar **out_initiator_email,
+ gchar **out_folder_entry_id)
+{
+ xmlDoc *xml;
+ xmlXPathContext *xpath;
+
+ if (!xml_str || !*xml_str)
+ return FALSE;
+
+ xml = e_xml_parse_data (xml_str, strlen (xml_str));
+
+ if (!xml)
+ return FALSE;
+
+ xpath = e_xml_new_xpath_context_with_namespaces (xml,
+ "s", "http://schemas.microsoft.com/sharing/2008",
+ "e", "http://schemas.microsoft.com/exchange/sharing/2008",
+ NULL);
+
+ *out_datatype = e_xml_xpath_eval_as_string (xpath, "/s:SharingMessage/s:DataType");
+ *out_initiator_name = e_xml_xpath_eval_as_string (xpath, "/s:SharingMessage/s:Initiator/s:Name");
+ *out_initiator_email = e_xml_xpath_eval_as_string (xpath,
"/s:SharingMessage/s:Initiator/s:SmtpAddress");
+ *out_folder_entry_id = e_xml_xpath_eval_as_string (xpath,
"/s:SharingMessage/s:Invitation/s:Providers/s:Provider/e:FolderId");
+
+ xmlXPathFreeContext (xpath);
+ xmlFreeDoc (xml);
+
+ return *out_datatype && **out_datatype &&
+ *out_initiator_name && **out_initiator_name &&
+ *out_initiator_email && **out_initiator_email &&
+ *out_folder_entry_id && **out_folder_entry_id;
+}
+
+static gboolean
+emf_ews_sharing_metadata_format (EMailFormatterExtension *extension,
+ EMailFormatter *formatter,
+ EMailFormatterContext *context,
+ EMailPart *part,
+ GOutputStream *stream,
+ GCancellable *cancellable)
+{
+ EMailPartEwsSharingMetadata *sharing_part;
+ gboolean handled = TRUE;
+ GString *buffer = NULL;
+
+ if (!E_IS_MAIL_PART_EWS_SHARING_METADATA (part))
+ return FALSE;
+
+ sharing_part = E_MAIL_PART_EWS_SHARING_METADATA (part);
+
+ if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING ||
+ context->mode == E_MAIL_FORMATTER_MODE_RAW) {
+ gchar *datatype = NULL, *initiator_name = NULL, *initiator_email = NULL, *folder_entry_id =
NULL;
+
+ if (emf_ews_sharing_metadata (sharing_part->xml, &datatype, &initiator_name,
&initiator_email, &folder_entry_id)) {
+ ENamedParameters *params;
+ gchar *params_str, *info;
+
+ params = e_named_parameters_new ();
+
+ e_named_parameters_set (params, "email", initiator_email);
+ e_named_parameters_set (params, "folder_id", folder_entry_id);
+
+ params_str = e_named_parameters_to_string (params);
+
+ e_named_parameters_free (params);
+
+ buffer = g_string_sized_new (2048);
+
+ g_string_append (buffer, e_mail_formatter_get_sub_html_header (formatter));
+ /* No need for body margins within <iframe> */
+ g_string_append (buffer, "<style>body{ margin: 0; }</style>");
+
+ if (g_strcmp0 (datatype, "calendar") == 0) {
+ /* Translators: the first %s is replaced with a user name, the second %s is
replaced with an email address of that user */
+ info = g_strdup_printf (_("%s (%s) has invited you to view his or her
Microsoft Exchange calendar."), initiator_name, initiator_email);
+ } else {
+ /* Translators: the first %s is replaced with a user name, the second %s is
replaced with an email address of that user */
+ info = g_strdup_printf (_("%s (%s) has invited you to view his or her
Microsoft Exchange folder."), initiator_name, initiator_email);
+ }
+
+ e_util_markup_append_escaped (buffer,
+ "<div class=\"part-container -e-web-view-background-color
-e-web-view-text-color\" style=\"border: none; padding: 8px; margin: 0;\">%s<br>"
+ "<br>"
+ "%s<br>"
+ "<br>"
+ "<button type=\"button\" class=\"ews-sharing-metadata-btn\"
id=\"ews-sharing-metadata-btn\" value=\"%s\">%s</button></div></body></html>",
+ info,
+ _("Click the Subscribe button to add it to Evolution."),
+ params_str,
+ _("Subscribe"));
+
+ g_free (params_str);
+ g_free (info);
+ } else {
+ CamelMimePart *err_part;
+ EMailPart *mail_part;
+ const gchar *msg, *mime_type = "application/vnd.evolution.error";
+
+ msg = _("Failed to extract sharing information from provided data.");
+
+ err_part = camel_mime_part_new ();
+ camel_mime_part_set_content (err_part, msg, strlen (msg), mime_type);
+
+ mail_part = e_mail_part_new (err_part, e_mail_part_get_id (part));
+
+ handled = e_mail_formatter_format_as (formatter, context, mail_part, stream,
mime_type, cancellable);
+
+ g_object_unref (mail_part);
+ g_object_unref (err_part);
+ }
+
+ g_free (datatype);
+ g_free (initiator_name);
+ g_free (initiator_email);
+ g_free (folder_entry_id);
+ } else {
+ const gchar *default_charset, *charset;
+ gchar *uri;
+
+ default_charset = e_mail_formatter_get_default_charset (formatter);
+ charset = e_mail_formatter_get_charset (formatter);
+
+ if (!default_charset)
+ default_charset = "";
+ if (!charset)
+ charset = "";
+
+ uri = e_mail_part_build_uri (
+ e_mail_part_list_get_folder (context->part_list),
+ e_mail_part_list_get_message_uid (context->part_list),
+ "part_id", G_TYPE_STRING, e_mail_part_get_id (part),
+ "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+ "formatter_default_charset", G_TYPE_STRING, default_charset,
+ "formatter_charset", G_TYPE_STRING, charset,
+ NULL);
+
+ buffer = g_string_sized_new (256);
+
+ g_string_append_printf (buffer,
+ "<div class=\"part-container-nostyle\" >"
+ "<iframe width=\"100%%\" height=\"10\""
+ " id=\"%s\" name=\"%s\" "
+ " frameborder=\"0\" src=\"%s\" "
+ " class=\"-e-mail-formatter-frame-color %s"
+ " -e-web-view-text-color\" >"
+ "</iframe>"
+ "</div>",
+ e_mail_part_get_id (part),
+ e_mail_part_get_id (part),
+ uri,
+ e_mail_part_get_frame_security_style (part));
+
+ g_free (uri);
+ }
+
+ if (buffer) {
+ g_output_stream_write_all (stream, buffer->str, buffer->len, NULL, cancellable, NULL);
+
+ g_string_free (buffer, TRUE);
+ }
+
+ return handled;
+}
+
+static void
+e_mail_formatter_ews_sharing_metadata_class_init (EMailFormatterExtensionClass *klass)
+{
+ klass->display_name = _("EWS Sharing Metadata");
+ klass->description = _("Display part as EWS sharing metadata");
+ klass->mime_types = formatter_mime_types;
+ klass->format = emf_ews_sharing_metadata_format;
+}
+
+static void
+e_mail_formatter_ews_sharing_metadata_class_finalize (EMailFormatterExtensionClass *klass)
+{
+}
+
+static void
+e_mail_formatter_ews_sharing_metadata_init (EMailFormatterExtension *extension)
+{
+}
+
+void
+e_mail_formatter_ews_sharing_metadata_type_register (GTypeModule *type_module)
+{
+ e_mail_formatter_ews_sharing_metadata_register_type (type_module);
+}
diff --git a/src/EWS/evolution/e-mail-formatter-ews-sharing-metadata.h
b/src/EWS/evolution/e-mail-formatter-ews-sharing-metadata.h
new file mode 100644
index 00000000..d28f49c7
--- /dev/null
+++ b/src/EWS/evolution/e-mail-formatter-ews-sharing-metadata.h
@@ -0,0 +1,18 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef E_MAIL_FORMATTER_EWS_SHARING_METADATA_H
+#define E_MAIL_FORMATTER_EWS_SHARING_METADATA_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_formatter_ews_sharing_metadata_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_FORMATTER_EWS_SHARING_METADATA_H */
diff --git a/src/EWS/evolution/e-mail-parser-ews-multipart-mixed.c
b/src/EWS/evolution/e-mail-parser-ews-multipart-mixed.c
new file mode 100644
index 00000000..c8b587f9
--- /dev/null
+++ b/src/EWS/evolution/e-mail-parser-ews-multipart-mixed.c
@@ -0,0 +1,103 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-ews-config.h"
+
+#include <em-format/e-mail-parser.h>
+#include <em-format/e-mail-parser-extension.h>
+
+#include "e-mail-parser-ews-sharing-metadata.h"
+#include "e-mail-parser-ews-multipart-mixed.h"
+
+typedef EMailParserExtension EMailParserEwsMultipartMixed;
+typedef EMailParserExtensionClass EMailParserEwsMultipartMixedClass;
+
+GType e_mail_parser_ews_multipart_mixed_get_type (void);
+
+G_DEFINE_DYNAMIC_TYPE (EMailParserEwsMultipartMixed, e_mail_parser_ews_multipart_mixed,
E_TYPE_MAIL_PARSER_EXTENSION)
+
+static const gchar *parser_mime_types[] = {
+ "multipart/mixed",
+ NULL
+};
+
+static gboolean
+emp_ews_mp_mixed_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
+{
+ CamelMultipart *mp;
+ gboolean handled = FALSE;
+
+ /* Allow this only in an EWS folder, because the EWS connection is needed */
+ if (!e_mail_parser_ews_sharing_metadata_is_ews_folder (parser, cancellable))
+ return FALSE;
+
+ mp = (CamelMultipart *) camel_medium_get_content (CAMEL_MEDIUM (part));
+
+ if (CAMEL_IS_MULTIPART (mp)) {
+ CamelMimePart *sharing_subpart = NULL;
+ gint ii, nparts, ntexts = 0, nsharings = 0;
+
+ nparts = camel_multipart_get_number (mp);
+
+ for (ii = 0; ii < nparts; ii++) {
+ CamelMimePart *subpart;
+ CamelContentType *ct;
+
+ subpart = camel_multipart_get_part (mp, ii);
+ ct = camel_mime_part_get_content_type (subpart);
+
+ if (ct && (camel_content_type_is (ct, "text", "plain") || camel_content_type_is (ct,
"text", "html"))) {
+ ntexts++;
+ } else if (ct && camel_content_type_is (ct, "application", "x-sharing-metadata-xml"))
{
+ sharing_subpart = subpart;
+ nsharings++;
+ }
+ }
+
+ /* Hide the text parts only if there is only a single sharing subpart */
+ if (nsharings == 1 && nsharings + ntexts == nparts) {
+ gint len;
+
+ len = part_id->len;
+
+ g_string_append_printf (part_id, ".mixed.ews-sharing");
+ handled = e_mail_parser_parse_part (parser, sharing_subpart, part_id, cancellable,
out_mail_parts);
+ g_string_truncate (part_id, len);
+ }
+ }
+
+ return handled;
+}
+
+static void
+e_mail_parser_ews_multipart_mixed_class_init (EMailParserExtensionClass *klass)
+{
+ klass->mime_types = parser_mime_types;
+ klass->priority = G_PRIORITY_LOW - 1;
+ klass->flags = E_MAIL_PARSER_EXTENSION_COMPOUND_TYPE;
+ klass->parse = emp_ews_mp_mixed_parse;
+}
+
+static void
+e_mail_parser_ews_multipart_mixed_class_finalize (EMailParserExtensionClass *klass)
+{
+}
+
+static void
+e_mail_parser_ews_multipart_mixed_init (EMailParserExtension *extension)
+{
+}
+
+void
+e_mail_parser_ews_multipart_mixed_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_ews_multipart_mixed_register_type (type_module);
+}
diff --git a/src/EWS/evolution/e-mail-parser-ews-multipart-mixed.h
b/src/EWS/evolution/e-mail-parser-ews-multipart-mixed.h
new file mode 100644
index 00000000..4be321ad
--- /dev/null
+++ b/src/EWS/evolution/e-mail-parser-ews-multipart-mixed.h
@@ -0,0 +1,18 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef E_MAIL_PARSER_EWS_MULTIPART_MIXED_H
+#define E_MAIL_PARSER_EWS_MULTIPART_MIXED_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_ews_multipart_mixed_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_EWS_MULTIPART_MIXED_H */
diff --git a/src/EWS/evolution/e-mail-parser-ews-sharing-metadata.c
b/src/EWS/evolution/e-mail-parser-ews-sharing-metadata.c
new file mode 100644
index 00000000..99217b87
--- /dev/null
+++ b/src/EWS/evolution/e-mail-parser-ews-sharing-metadata.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-ews-config.h"
+
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+
+#include "camel/camel-ews-folder.h"
+#include "e-mail-part-ews-sharing-metadata.h"
+
+#include "e-mail-parser-ews-sharing-metadata.h"
+
+typedef EMailParserExtension EMailParserEwsSharingMetadata;
+typedef EMailParserExtensionClass EMailParserEwsSharingMetadataClass;
+
+GType e_mail_parser_ews_sharing_metadata_get_type (void);
+
+G_DEFINE_DYNAMIC_TYPE (EMailParserEwsSharingMetadata, e_mail_parser_ews_sharing_metadata,
E_TYPE_MAIL_PARSER_EXTENSION)
+
+static const gchar *parser_mime_types[] = {
+ "application/x-sharing-metadata-xml",
+ NULL
+};
+
+static gboolean
+emp_ews_sharing_metadata_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable,
+ GQueue *out_mail_parts)
+{
+ EMailPart *mail_part;
+ CamelDataWrapper *content;
+ CamelStream *stream;
+ GByteArray *byte_array;
+ gchar *xml;
+ gint len;
+
+ /* Allow this only in an EWS folder, because the EWS connection is needed */
+ if (!e_mail_parser_ews_sharing_metadata_is_ews_folder (parser, cancellable))
+ return FALSE;
+
+ /* This is non-gui thread. Download the part for using in the main thread */
+ content = camel_medium_get_content ((CamelMedium *) part);
+
+ byte_array = g_byte_array_new ();
+ stream = camel_stream_mem_new_with_byte_array (byte_array);
+ camel_data_wrapper_decode_to_stream_sync (content, stream, NULL, NULL);
+
+ if (byte_array->len == 0)
+ xml = NULL;
+ else
+ xml = g_strndup ((const gchar *) byte_array->data, byte_array->len);
+
+ g_object_unref (stream);
+
+ if (!xml)
+ return FALSE;
+
+ len = part_id->len;
+ g_string_append_printf (part_id, ".ews-sharing-xml");
+
+ mail_part = e_mail_part_ews_sharing_metadata_new (part, part_id->str);
+ mail_part->force_inline = TRUE;
+ e_mail_part_set_mime_type (mail_part, parser_mime_types[0]);
+ E_MAIL_PART_EWS_SHARING_METADATA (mail_part)->xml = xml;
+
+ g_queue_push_tail (out_mail_parts, mail_part);
+
+ g_string_truncate (part_id, len);
+
+ return TRUE;
+}
+
+static void
+e_mail_parser_ews_sharing_metadata_class_init (EMailParserExtensionClass *klass)
+{
+ klass->mime_types = parser_mime_types;
+ klass->flags = E_MAIL_PARSER_EXTENSION_INLINE_DISPOSITION;
+ klass->parse = emp_ews_sharing_metadata_parse;
+}
+
+static void
+e_mail_parser_ews_sharing_metadata_class_finalize (EMailParserExtensionClass *klass)
+{
+}
+
+static void
+e_mail_parser_ews_sharing_metadata_init (EMailParserExtension *sharind_metadata)
+{
+}
+
+void
+e_mail_parser_ews_sharing_metadata_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_ews_sharing_metadata_register_type (type_module);
+}
+
+gboolean
+e_mail_parser_ews_sharing_metadata_is_ews_folder (EMailParser *parser,
+ GCancellable *operation)
+{
+ EMailPartList *part_list;
+ CamelFolder *folder;
+ gboolean is_ews_folder;
+
+ part_list = e_mail_parser_ref_part_list_for_operation (parser, operation);
+
+ if (!part_list)
+ return FALSE;
+
+ folder = e_mail_part_list_get_folder (part_list);
+ is_ews_folder = CAMEL_IS_EWS_FOLDER (folder);
+
+ g_object_unref (part_list);
+
+ return is_ews_folder;
+}
diff --git a/src/EWS/evolution/e-mail-parser-ews-sharing-metadata.h
b/src/EWS/evolution/e-mail-parser-ews-sharing-metadata.h
new file mode 100644
index 00000000..586b57fa
--- /dev/null
+++ b/src/EWS/evolution/e-mail-parser-ews-sharing-metadata.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef E_MAIL_PARSER_EWS_SHARING_METADATA_H
+#define E_MAIL_PARSER_EWS_SHARING_METADATA_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <em-format/e-mail-parser.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_ews_sharing_metadata_type_register (GTypeModule *type_module);
+gboolean e_mail_parser_ews_sharing_metadata_is_ews_folder (EMailParser *parser,
+ GCancellable *operation);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_EWS_SHARING_METADATA_H */
diff --git a/src/EWS/evolution/e-mail-part-ews-sharing-metadata.c
b/src/EWS/evolution/e-mail-part-ews-sharing-metadata.c
new file mode 100644
index 00000000..19b03de1
--- /dev/null
+++ b/src/EWS/evolution/e-mail-part-ews-sharing-metadata.c
@@ -0,0 +1,233 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-ews-config.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <e-util/e-util.h>
+#include <mail/e-mail-display.h>
+#include <shell/e-shell-window.h>
+
+#include "camel/camel-ews-folder.h"
+#include "camel/camel-ews-store.h"
+
+#include "e-ews-subscribe-foreign-folder.h"
+
+#include "e-mail-part-ews-sharing-metadata.h"
+
+G_DEFINE_DYNAMIC_TYPE (EMailPartEwsSharingMetadata, e_mail_part_ews_sharing_metadata, E_TYPE_MAIL_PART)
+
+typedef struct _SubscribeData {
+ CamelEwsStore *ews_store;
+ EEwsConnection *cnc;
+ ENamedParameters *params;
+} SubscribeData;
+
+static void
+subscribe_data_free (gpointer ptr)
+{
+ SubscribeData *sd = ptr;
+
+ if (sd) {
+ g_clear_object (&sd->ews_store);
+ g_clear_object (&sd->cnc);
+ e_named_parameters_free (sd->params);
+ g_slice_free (SubscribeData, sd);
+ }
+}
+
+static void
+ews_sharing_metadata_subscribe_thread (EAlertSinkThreadJobData *job_data,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SubscribeData *sd = user_data;
+ EwsFolderId fid;
+ EEwsFolder *folder = NULL;
+ const gchar *email;
+ gchar *folder_id = NULL;
+ gchar *display_name = NULL;
+ GError *local_error = NULL;
+
+ g_return_if_fail (sd != NULL);
+
+ if (!sd->cnc) {
+ g_set_error_literal (error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE,
+ _("Cannot subscribe EWS folders in offline mode"));
+ return;
+ }
+
+ email = e_named_parameters_get (sd->params, "email");
+
+ if (!e_ews_connection_convert_id_sync (sd->cnc, G_PRIORITY_DEFAULT, email,
+ e_named_parameters_get (sd->params, "folder_id"),
+ "HexEntryId", "EwsId", &folder_id, cancellable, error)) {
+ return;
+ }
+
+ fid.id = folder_id;
+ fid.change_key = NULL;
+ fid.is_distinguished_id = FALSE;
+
+ if (e_ews_connection_get_folder_info_sync (sd->cnc, G_PRIORITY_DEFAULT, email, &fid, &folder,
cancellable, &local_error)) {
+ if (e_ews_folder_get_folder_type (folder) == E_EWS_FOLDER_TYPE_UNKNOWN) {
+ local_error = g_error_new_literal (EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_FOLDERNOTFOUND,
+ _("Cannot add folder, cannot determine folder’s type"));
+ } else {
+ e_ews_folder_set_foreign (folder, TRUE);
+
+ if (!e_ews_subscribe_foreign_folder_resolve_name_sync (sd->cnc, email, &display_name,
NULL, cancellable, NULL))
+ display_name = NULL;
+
+ e_ews_subscrive_foreign_folder_subscribe_sync (sd->ews_store, folder,
+ display_name, email, _("Folder"), FALSE, cancellable, &local_error);
+ }
+ } else if (!local_error ||
+ g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND) ||
+ g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_FOLDERNOTFOUND)) {
+ g_clear_error (&local_error);
+ local_error = g_error_new (
+ EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_FOLDERNOTFOUND,
+ _("Folder “%s” not found. Either it does not exist or you do not have permission to
access it."),
+ e_named_parameters_get (sd->params, "folder_id"));
+ }
+
+ if (local_error) {
+ g_propagate_error (error, local_error);
+ } else {
+ e_alert_sink_thread_job_set_alert_ident (job_data, "ews:folder-subscribe-info");
+ e_alert_sink_thread_job_set_alert_arg_0 (job_data, display_name ? display_name : email);
+
+ /* Create a fake error, to give a feedback about successful subscribe of the folder */
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "");
+ }
+
+ g_clear_object (&folder);
+ g_free (display_name);
+ g_free (folder_id);
+}
+
+static void
+ews_sharing_metadata_btn_clicked_cb (EWebView *web_view,
+ const gchar *iframe_id,
+ const gchar *element_id,
+ const gchar *element_class,
+ const gchar *element_value,
+ const GtkAllocation *element_position,
+ gpointer user_data)
+{
+ EMailPartList *part_list;
+ EAlertSink *alert_sink = NULL;
+ EActivity *activity;
+ CamelFolder *folder;
+ CamelStore *store;
+ GtkWidget *widget;
+ SubscribeData *sd;
+
+ if (!element_value || !*element_value || !E_IS_MAIL_DISPLAY (web_view))
+ return;
+
+ part_list = e_mail_display_get_part_list (E_MAIL_DISPLAY (web_view));
+ folder = part_list ? e_mail_part_list_get_folder (part_list) : NULL;
+
+ if (!CAMEL_IS_EWS_FOLDER (folder))
+ return;
+
+ store = camel_folder_get_parent_store (folder);
+
+ if (!CAMEL_IS_EWS_STORE (store))
+ return;
+
+ widget = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
+
+ if (E_IS_SHELL_WINDOW (widget))
+ alert_sink = E_ALERT_SINK (widget);
+
+ if (!alert_sink)
+ alert_sink = E_ALERT_SINK (web_view);
+
+ sd = g_slice_new (SubscribeData);
+ sd->ews_store = g_object_ref (store);
+ sd->cnc = camel_ews_store_ref_connection (CAMEL_EWS_STORE (store));
+ sd->params = e_named_parameters_new_string (element_value);
+
+ activity = e_alert_sink_submit_thread_job (alert_sink,
+ _("Subscribing EWS folder…"), "ews:folder-subscribe-error", NULL,
+ ews_sharing_metadata_subscribe_thread, sd, subscribe_data_free);
+
+ g_clear_object (&activity);
+}
+
+static void
+mail_part_ews_sharing_metadata_content_loaded (EMailPart *part,
+ EWebView *web_view,
+ const gchar *iframe_id)
+{
+ g_return_if_fail (E_IS_MAIL_PART_EWS_SHARING_METADATA (part));
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ if (g_strcmp0 ((iframe_id && *iframe_id) ? iframe_id : NULL, e_mail_part_get_id (part)) != 0)
+ return;
+
+ e_web_view_register_element_clicked (web_view, "ews-sharing-metadata-btn",
+ ews_sharing_metadata_btn_clicked_cb, NULL);
+}
+
+static void
+mail_part_ews_sharing_metadata_finalize (GObject *object)
+{
+ EMailPartEwsSharingMetadata *part = E_MAIL_PART_EWS_SHARING_METADATA (object);
+
+ g_clear_pointer (&part->xml, g_free);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_mail_part_ews_sharing_metadata_parent_class)->finalize (object);
+}
+
+static void
+e_mail_part_ews_sharing_metadata_class_init (EMailPartEwsSharingMetadataClass *klass)
+{
+ GObjectClass *object_class;
+ EMailPartClass *mail_part_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = mail_part_ews_sharing_metadata_finalize;
+
+ mail_part_class = E_MAIL_PART_CLASS (klass);
+ mail_part_class->content_loaded = mail_part_ews_sharing_metadata_content_loaded;
+}
+
+static void
+e_mail_part_ews_sharing_metadata_class_finalize (EMailPartEwsSharingMetadataClass *klass)
+{
+}
+
+static void
+e_mail_part_ews_sharing_metadata_init (EMailPartEwsSharingMetadata *part)
+{
+}
+
+void
+e_mail_part_ews_sharing_metadata_type_register (GTypeModule *type_module)
+{
+ /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+ * function, so we have to wrap it with a public function in
+ * order to register types from a separate compilation unit. */
+ e_mail_part_ews_sharing_metadata_register_type (type_module);
+}
+
+EMailPart *
+e_mail_part_ews_sharing_metadata_new (CamelMimePart *mime_part,
+ const gchar *id)
+{
+ g_return_val_if_fail (id != NULL, NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_PART_EWS_SHARING_METADATA,
+ "id", id, "mime-part", mime_part, NULL);
+}
diff --git a/src/EWS/evolution/e-mail-part-ews-sharing-metadata.h
b/src/EWS/evolution/e-mail-part-ews-sharing-metadata.h
new file mode 100644
index 00000000..c62a7abf
--- /dev/null
+++ b/src/EWS/evolution/e-mail-part-ews-sharing-metadata.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef E_MAIL_PART_EWS_SHARING_METADATA_H
+#define E_MAIL_PART_EWS_SHARING_METADATA_H
+
+#include <em-format/e-mail-part.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_PART_EWS_SHARING_METADATA \
+ (e_mail_part_ews_sharing_metadata_get_type ())
+#define E_MAIL_PART_EWS_SHARING_METADATA(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_PART_EWS_SHARING_METADATA, EMailPartEwsSharingMetadata))
+#define E_MAIL_PART_EWS_SHARING_METADATA_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_PART_EWS_SHARING_METADATA, EMailPartEwsSharingMetadataClass))
+#define E_IS_MAIL_PART_EWS_SHARING_METADATA(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_PART_EWS_SHARING_METADATA))
+#define E_IS_MAIL_PART_EWS_SHARING_METADATA_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_PART_EWS_SHARING_METADATA))
+#define E_MAIL_PART_EWS_SHARING_METADATA_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_PART_EWS_SHARING_METADATA, EMailPartEwsSharingMetadataClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailPartEwsSharingMetadata EMailPartEwsSharingMetadata;
+typedef struct _EMailPartEwsSharingMetadataClass EMailPartEwsSharingMetadataClass;
+typedef struct _EMailPartEwsSharingMetadataPrivate EMailPartEwsSharingMetadataPrivate;
+
+struct _EMailPartEwsSharingMetadata {
+ EMailPart parent;
+
+ gchar *xml;
+};
+
+struct _EMailPartEwsSharingMetadataClass {
+ EMailPartClass parent_class;
+};
+
+GType e_mail_part_ews_sharing_metadata_get_type (void) G_GNUC_CONST;
+void e_mail_part_ews_sharing_metadata_type_register (GTypeModule *type_module);
+EMailPart * e_mail_part_ews_sharing_metadata_new (CamelMimePart *mime_part,
+ const gchar *id);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PART_EWS_SHARING_METADATA_H */
diff --git a/src/EWS/evolution/module-ews-configuration.c b/src/EWS/evolution/module-ews-configuration.c
index 978e7cb3..747fc8db 100644
--- a/src/EWS/evolution/module-ews-configuration.c
+++ b/src/EWS/evolution/module-ews-configuration.c
@@ -19,6 +19,10 @@
#include "e-mail-config-ews-offline-options.h"
#include "e-mail-config-ews-ooo-page.h"
#include "e-mail-config-ews-folder-sizes-page.h"
+#include "e-mail-formatter-ews-sharing-metadata.h"
+#include "e-mail-parser-ews-multipart-mixed.h"
+#include "e-mail-parser-ews-sharing-metadata.h"
+#include "e-mail-part-ews-sharing-metadata.h"
#include "e-ews-ooo-notificator.h"
#include "e-ews-config-lookup.h"
#include "e-ews-photo-source.h"
@@ -49,6 +53,10 @@ e_module_load (GTypeModule *type_module)
e_mail_config_ews_delegates_page_type_register (type_module);
e_mail_config_ews_ooo_page_type_register (type_module);
e_mail_config_ews_folder_sizes_page_type_register (type_module);
+ e_mail_formatter_ews_sharing_metadata_type_register (type_module);
+ e_mail_parser_ews_multipart_mixed_type_register (type_module);
+ e_mail_parser_ews_sharing_metadata_type_register (type_module);
+ e_mail_part_ews_sharing_metadata_type_register (type_module);
e_ews_config_lookup_type_register (type_module);
e_ews_config_ui_extension_type_register (type_module);
e_ews_ooo_notificator_type_register (type_module);
diff --git a/src/EWS/evolution/module-ews-configuration.error.xml
b/src/EWS/evolution/module-ews-configuration.error.xml
index 33a01288..3d915ac1 100644
--- a/src/EWS/evolution/module-ews-configuration.error.xml
+++ b/src/EWS/evolution/module-ews-configuration.error.xml
@@ -25,4 +25,14 @@
<_primary>Your Exchange account “{0}” has the status set as “Out of Office”.</_primary>
</error>
+ <error type="error" id="folder-subscribe-error">
+ <_primary>Failed to subscribe user folder.</_primary>
+ <_secondary>The reported error was “{0}”.</_secondary>
+ </error>
+
+ <error type="info" id="folder-subscribe-info">
+ <_primary>Folder had been subscribed.</_primary>
+ <_secondary>Folder of user “{0}” had been subscribed successfully.</_secondary>
+ </error>
+
</error-list>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]