[35fae39286f862cb505a3f0cac0b0d506f9a407cf9227d3c2ae2c67d5ec0d0f5/wip/mcrha/office365] Implement mail message send (CamelO365Transport)
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [35fae39286f862cb505a3f0cac0b0d506f9a407cf9227d3c2ae2c67d5ec0d0f5/wip/mcrha/office365] Implement mail message send (CamelO365Transport)
- Date: Wed, 8 Jul 2020 09:45:03 +0000 (UTC)
commit 78db8b9c1da098007366e1996a44cc7f55b5ea68
Author: Milan Crha <mcrha redhat com>
Date: Wed Jul 8 11:44:56 2020 +0200
Implement mail message send (CamelO365Transport)
src/Office365/camel/camel-o365-folder.c | 2 +-
src/Office365/camel/camel-o365-transport.c | 278 +++++++++++++++++++++++++----
src/Office365/camel/camel-o365-utils.c | 172 ++++++++++++++----
src/Office365/camel/camel-o365-utils.h | 13 +-
src/Office365/common/e-o365-connection.c | 79 ++++++++
src/Office365/common/e-o365-connection.h | 12 ++
6 files changed, 485 insertions(+), 71 deletions(-)
---
diff --git a/src/Office365/camel/camel-o365-folder.c b/src/Office365/camel/camel-o365-folder.c
index e085ebb6..b0c89027 100644
--- a/src/Office365/camel/camel-o365-folder.c
+++ b/src/Office365/camel/camel-o365-folder.c
@@ -628,7 +628,7 @@ o365_folder_append_message_sync (CamelFolder *folder,
return FALSE;
success = camel_o365_utils_create_message_sync (cnc, camel_o365_folder_get_id (CAMEL_O365_FOLDER
(folder)),
- message, info, FALSE, appended_uid, cancellable, &local_error);
+ message, info, appended_uid, cancellable, &local_error);
g_clear_object (&cnc);
diff --git a/src/Office365/camel/camel-o365-transport.c b/src/Office365/camel/camel-o365-transport.c
index 27bbfe91..985a4efa 100644
--- a/src/Office365/camel/camel-o365-transport.c
+++ b/src/Office365/camel/camel-o365-transport.c
@@ -21,42 +21,143 @@
#include <glib/gi18n-lib.h>
+#include <libemail-engine/libemail-engine.h>
+
#include "common/camel-o365-settings.h"
+#include "common/e-o365-connection.h"
+#include "camel-o365-store.h"
+#include "camel-o365-utils.h"
#include "camel-o365-transport.h"
+#define LOCK(_transport) g_mutex_lock (&_transport->priv->property_lock)
+#define UNLOCK(_transport) g_mutex_unlock (&_transport->priv->property_lock)
+
struct _CamelO365TransportPrivate
{
GMutex property_lock;
- /*EO365Connection *connection;*/
+ EO365Connection *cnc;
};
G_DEFINE_TYPE_WITH_PRIVATE (CamelO365Transport, camel_o365_transport, CAMEL_TYPE_TRANSPORT)
-/*static EO365Connection *
+static gboolean
+o365_transport_is_server_side_sent_folder (CamelService *service,
+ GCancellable *cancellable)
+{
+ CamelSession *session;
+ ESourceRegistry *registry;
+ ESource *sibling, *source = NULL;
+ gboolean is_server_side = FALSE;
+
+ g_return_val_if_fail (CAMEL_IS_O365_TRANSPORT (service), FALSE);
+
+ session = camel_service_ref_session (service);
+
+ if (session && E_IS_MAIL_SESSION (session))
+ registry = g_object_ref (e_mail_session_get_registry (E_MAIL_SESSION (session)));
+ else
+ registry = e_source_registry_new_sync (cancellable, NULL);
+
+ if (!registry) {
+ g_clear_object (&session);
+ return FALSE;
+ }
+
+ sibling = e_source_registry_ref_source (registry, camel_service_get_uid (service));
+
+ if (sibling) {
+ GList *sources, *siter;
+
+ sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_MAIL_SUBMISSION);
+
+ for (siter = sources; siter; siter = siter->next) {
+ source = siter->data;
+
+ if (!source || g_strcmp0 (e_source_get_parent (source), e_source_get_parent
(sibling)) != 0 ||
+ !e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION) ||
+ !e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION))
+ source = NULL;
+ else
+ break;
+ }
+
+ if (source &&
+ e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION) &&
+ e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION)) {
+ ESourceMailSubmission *subm_extension;
+ CamelStore *store = NULL;
+ gchar *folder_name = NULL;
+
+ subm_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION);
+
+ /* Copy messages on the server side only if the replies
+ might not be saved to the original folder, which is handled
+ by the evolution itself. */
+ if (!e_source_mail_submission_get_replies_to_origin_folder (subm_extension) &&
+ e_source_mail_submission_get_sent_folder (subm_extension) &&
+ e_mail_folder_uri_parse (session,
+ e_source_mail_submission_get_sent_folder (subm_extension),
+ &store, &folder_name, NULL) && CAMEL_IS_O365_STORE (store)) {
+ CamelO365Store *o365_store = CAMEL_O365_STORE (store);
+ CamelO365StoreSummary *o365_store_summary;
+ gchar *folder_id_str;
+
+ o365_store_summary = camel_o365_store_ref_store_summary (o365_store);
+ folder_id_str = camel_o365_store_summary_dup_folder_id_for_full_name
(o365_store_summary, folder_name);
+ if (folder_id_str && *folder_id_str) {
+ guint32 flags;
+
+ flags = camel_o365_store_summary_get_folder_flags
(o365_store_summary, folder_id_str);
+
+ if ((flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_SENT) {
+ is_server_side = TRUE;
+ }
+ }
+
+ g_clear_object (&o365_store_summary);
+ g_free (folder_id_str);
+ }
+
+ g_clear_object (&store);
+ g_free (folder_name);
+ }
+
+ g_list_free_full (sources, g_object_unref);
+ g_object_unref (sibling);
+ }
+
+ g_object_unref (registry);
+ g_clear_object (&session);
+
+ return is_server_side;
+}
+
+static EO365Connection *
o365_transport_ref_connection (CamelO365Transport *o365_transport)
{
- EO365Connection *connection = NULL;
+ EO365Connection *cnc = NULL;
g_return_val_if_fail (CAMEL_IS_O365_TRANSPORT (o365_transport), NULL);
- g_mutex_lock (&o365_transport->priv->property_lock);
+ LOCK (o365_transport);
- if (o365_transport->priv->connection)
- connection = g_object_ref (o365_transport->priv->connection);
+ if (o365_transport->priv->cnc)
+ cnc = g_object_ref (o365_transport->priv->cnc);
- g_mutex_unlock (&o365_transport->priv->property_lock);
+ UNLOCK (o365_transport);
- return connection;
-}*/
+ return cnc;
+}
static gboolean
o365_transport_connect_sync (CamelService *service,
GCancellable *cancellable,
GError **error)
{
- CamelSession *session;
- gboolean success;
+ CamelO365Transport *o365_transport;
+ EO365Connection *cnc;
+ gboolean success = FALSE;
/* Chain up to parent's method. */
if (!CAMEL_SERVICE_CLASS (camel_o365_transport_parent_class)->connect_sync (service, cancellable,
error))
@@ -65,17 +166,29 @@ o365_transport_connect_sync (CamelService *service,
if (camel_service_get_connection_status (service) == CAMEL_SERVICE_DISCONNECTED)
return FALSE;
- /*connection = o365_transport_ref_connection (CAMEL_O365_TRANSPORT (service));
- if (connection) {
- g_object_unref (connection);
- return TRUE;
- }*/
+ o365_transport = CAMEL_O365_TRANSPORT (service);
+ cnc = o365_transport_ref_connection (o365_transport);
- session = camel_service_ref_session (service);
+ if (!cnc) {
+ LOCK (o365_transport);
+
+ o365_transport->priv->cnc = camel_o365_utils_new_connection (service, NULL);
+
+ UNLOCK (o365_transport);
+ }
- success = camel_session_authenticate_sync (session, service, "Office365", cancellable, error);
+ if (cnc) {
+ CamelSession *session;
- g_object_unref (session);
+ session = camel_service_ref_session (service);
+
+ success = camel_session_authenticate_sync (session, service, "Office365", cancellable, error);
+
+ g_clear_object (&session);
+ g_clear_object (&cnc);
+ } else {
+ g_set_error_literal (error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, _("Failed
to create connection"));
+ }
return success;
}
@@ -87,11 +200,21 @@ o365_transport_disconnect_sync (CamelService *service,
GError **error)
{
CamelO365Transport *o365_transport = CAMEL_O365_TRANSPORT (service);
+ EO365Connection *cnc;
+ gboolean success = TRUE;
+
+ cnc = o365_transport_ref_connection (o365_transport);
- g_mutex_lock (&o365_transport->priv->property_lock);
- /*g_clear_object (&o365_transport->priv->connection);*/
- g_mutex_unlock (&o365_transport->priv->property_lock);
+ if (cnc) {
+ success = e_o365_connection_disconnect_sync (cnc, cancellable, error);
+
+ g_clear_object (&cnc);
+ }
+
+ if (!success)
+ return FALSE;
+ /* Chain up to parent's method. */
return CAMEL_SERVICE_CLASS (camel_o365_transport_parent_class)->disconnect_sync (service, clean,
cancellable, error);
}
@@ -102,8 +225,31 @@ o365_transport_authenticate_sync (CamelService *service,
GError **error)
{
CamelAuthenticationResult result;
-
- result = CAMEL_AUTHENTICATION_ERROR;
+ CamelO365Transport *o365_transport;
+ EO365Connection *cnc;
+
+ o365_transport = CAMEL_O365_TRANSPORT (service);
+ cnc = o365_transport_ref_connection (o365_transport);
+
+ if (!cnc)
+ return CAMEL_AUTHENTICATION_ERROR;
+
+ switch (e_o365_connection_authenticate_sync (cnc, cancellable, error)) {
+ case E_SOURCE_AUTHENTICATION_ERROR:
+ case E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED:
+ default:
+ result = CAMEL_AUTHENTICATION_ERROR;
+ break;
+ case E_SOURCE_AUTHENTICATION_ACCEPTED:
+ result = CAMEL_AUTHENTICATION_ACCEPTED;
+ break;
+ case E_SOURCE_AUTHENTICATION_REJECTED:
+ case E_SOURCE_AUTHENTICATION_REQUIRED:
+ result = CAMEL_AUTHENTICATION_REJECTED;
+ break;
+ }
+
+ g_clear_object (&cnc);
return result;
}
@@ -115,9 +261,9 @@ o365_transport_get_name (CamelService *service,
gchar *name;
if (brief)
- name = g_strdup (_("Office365 server"));
+ name = g_strdup (_("Office 365 server"));
else
- name = g_strdup (_("Mail delivery via Microsoft Office365"));
+ name = g_strdup (_("Mail delivery via Microsoft Office 365"));
return name;
}
@@ -131,7 +277,77 @@ o365_send_to_sync (CamelTransport *transport,
GCancellable *cancellable,
GError **error)
{
- return FALSE;
+ CamelInternetAddress *use_from;
+ CamelService *service;
+ EO365Connection *cnc;
+ JsonBuilder *builder;
+ gchar *appended_id = NULL;
+ gboolean is_server_side_sent;
+ gboolean success = FALSE;
+
+ service = CAMEL_SERVICE (transport);
+
+ if (CAMEL_IS_INTERNET_ADDRESS (from))
+ use_from = CAMEL_INTERNET_ADDRESS (from);
+ else
+ use_from = camel_mime_message_get_from (message);
+
+ if (!use_from || camel_address_length (CAMEL_ADDRESS (use_from)) == 0) {
+ g_set_error_literal (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Cannot send message with no From address"));
+ return FALSE;
+
+ } else if (camel_address_length (CAMEL_ADDRESS (use_from)) > 1) {
+ g_set_error_literal (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Office 365 server cannot send message with multiple From addresses"));
+ return FALSE;
+
+ } else {
+ const gchar *used_email = NULL;
+
+ if (!camel_internet_address_get (use_from, 0, NULL, &used_email)) {
+ g_set_error_literal (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Failed to read From address"));
+ return FALSE;
+ }
+ }
+
+ cnc = o365_transport_ref_connection (CAMEL_O365_TRANSPORT (service));
+
+ if (!cnc) {
+ g_set_error_literal (
+ error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_NOT_CONNECTED,
+ _("Service not connected"));
+ return FALSE;
+ }
+
+ is_server_side_sent = o365_transport_is_server_side_sent_folder (service, cancellable);
+
+ if (is_server_side_sent && out_sent_message_saved)
+ *out_sent_message_saved = TRUE;
+
+ builder = json_builder_new_immutable ();
+ e_o365_json_begin_object_member (builder, NULL);
+ e_o365_json_begin_object_member (builder, "message");
+
+ success = camel_o365_utils_fill_message_object_sync (builder, message, NULL, from, recipients, TRUE,
NULL, cancellable, error);
+
+ e_o365_json_end_object_member (builder); /* message */
+
+ if (!is_server_side_sent)
+ e_o365_json_add_boolean_member (builder, "saveToSentItems", FALSE);
+
+ e_o365_json_end_object_member (builder);
+
+ success = success && e_o365_connection_send_mail_sync (cnc, NULL, builder, cancellable, error);
+
+ g_object_unref (cnc);
+ g_free (appended_id);
+
+ return success;
}
static void
@@ -139,9 +355,11 @@ o365_transport_dispose (GObject *object)
{
CamelO365Transport *o365_transport = CAMEL_O365_TRANSPORT (object);
- g_mutex_lock (&o365_transport->priv->property_lock);
- /*g_clear_object (&o365_transport->priv->connection);*/
- g_mutex_unlock (&o365_transport->priv->property_lock);
+ LOCK (o365_transport);
+
+ g_clear_object (&o365_transport->priv->cnc);
+
+ UNLOCK (o365_transport);
/* Chain up to parent's method. */
G_OBJECT_CLASS (camel_o365_transport_parent_class)->dispose (object);
diff --git a/src/Office365/camel/camel-o365-utils.c b/src/Office365/camel/camel-o365-utils.c
index 20f51181..3d24749b 100644
--- a/src/Office365/camel/camel-o365-utils.c
+++ b/src/Office365/camel/camel-o365-utils.c
@@ -209,7 +209,9 @@ static void
o365_utils_add_address_array (JsonBuilder *builder,
CamelInternetAddress *addr,
void (* begin_func) (JsonBuilder *builder),
- void (* end_func) (JsonBuilder *builder))
+ void (* end_func) (JsonBuilder *builder),
+ GHashTable *known_recipients,
+ CamelAddress *expected_recipients)
{
gint ii, len;
gboolean did_add = FALSE;
@@ -231,10 +233,36 @@ o365_utils_add_address_array (JsonBuilder *builder,
begin_func (builder);
}
+ if (known_recipients && address && *address)
+ g_hash_table_add (known_recipients, (gpointer) address);
+
e_o365_add_recipient (builder, NULL, name, address);
}
}
+ if (known_recipients && expected_recipients && CAMEL_IS_INTERNET_ADDRESS (expected_recipients)) {
+ CamelInternetAddress *iaddr = CAMEL_INTERNET_ADDRESS (expected_recipients);
+
+ len = camel_address_length (expected_recipients);
+
+ for (ii = 0; ii < len; ii++) {
+ const gchar *name = NULL, *address = NULL;
+
+ if (camel_internet_address_get (iaddr, 0, &name, &address) && address && *address &&
+ !g_hash_table_contains (known_recipients, address)) {
+ if (!did_add) {
+ did_add = TRUE;
+ begin_func (builder);
+ }
+
+ if (known_recipients && address && *address)
+ g_hash_table_add (known_recipients, (gpointer) address);
+
+ e_o365_add_recipient (builder, NULL, name, address);
+ }
+ }
+ }
+
if (did_add)
end_func (builder);
}
@@ -740,33 +768,52 @@ camel_o365_utils_add_message_flags (JsonBuilder *builder,
e_o365_mail_message_add_is_read (builder, (flags & CAMEL_MESSAGE_SEEN) != 0);
}
+static void
+o365_utils_add_attachment_object (JsonBuilder *builder,
+ CamelDataWrapper *dw,
+ GCancellable *cancellable)
+{
+ CamelContentType *ct;
+
+ ct = camel_data_wrapper_get_mime_type_field (dw);
+
+ e_o365_attachment_begin_attachment (builder, E_O365_ATTACHMENT_DATA_TYPE_FILE);
+
+ if (camel_content_type_is (ct, "application", "x-pkcs7-mime") ||
+ camel_content_type_is (ct, "application", "pkcs7-mime")) {
+ o365_utils_add_smime_encrypted_attachment (builder, dw, cancellable);
+ } else if (CAMEL_IS_MULTIPART_SIGNED (dw)) {
+ o365_utils_add_smime_signed_attachment (builder, dw, cancellable);
+ } else {
+ o365_utils_add_file_attachment (builder, dw, cancellable);
+ }
+
+ e_o365_json_end_object_member (builder);
+}
+
gboolean
-camel_o365_utils_create_message_sync (EO365Connection *cnc,
- const gchar *folder_id,
- CamelMimeMessage *message,
- CamelMessageInfo *info,
- gboolean is_send,
- gchar **out_appended_uid,
- GCancellable *cancellable,
- GError **error)
+camel_o365_utils_fill_message_object_sync (JsonBuilder *builder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ CamelAddress *override_from,
+ CamelAddress *override_recipients, /* it merges them, not really
override */
+ gboolean is_send,
+ GSList **out_attachments,
+ GCancellable *cancellable,
+ GError **error)
{
- JsonBuilder *builder;
- EO365MailMessage *appended_message = NULL;
CamelInternetAddress *addr, *sender = NULL;
CamelMimePart *body_part;
+ GHashTable *known_recipients = NULL;
GSList *attachments = NULL;
time_t tt;
gint offset = 0;
const gchar *tmp;
- gboolean success, request_read_receipt = FALSE;
+ gboolean success = TRUE, request_read_receipt = FALSE;
- g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (builder != NULL, FALSE);
g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE);
- builder = json_builder_new_immutable ();
-
- e_o365_json_begin_object_member (builder, NULL);
-
tmp = camel_mime_message_get_message_id (message);
if (tmp && *tmp)
e_o365_mail_message_add_internet_message_id (builder, tmp);
@@ -795,20 +842,31 @@ camel_o365_utils_create_message_sync (EO365Connection *cnc,
e_o365_mail_message_add_received_date_time (builder, tt);
}
- addr = camel_mime_message_get_from (message);
+ if (override_recipients)
+ known_recipients = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
+
+ if (override_from && CAMEL_IS_INTERNET_ADDRESS (override_from))
+ addr = CAMEL_INTERNET_ADDRESS (override_from);
+ else
+ addr = camel_mime_message_get_from (message);
o365_utils_add_address (builder, addr, e_o365_mail_message_add_from);
addr = camel_mime_message_get_reply_to (message);
- o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_reply_to,
e_o365_mail_message_end_reply_to);
+ o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_reply_to,
e_o365_mail_message_end_reply_to, NULL, NULL);
addr = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO);
- o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_to_recipients,
e_o365_mail_message_end_to_recipients);
+ o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_to_recipients,
e_o365_mail_message_end_to_recipients, known_recipients, NULL);
addr = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_CC);
- o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_cc_recipients,
e_o365_mail_message_end_cc_recipients);
+ o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_cc_recipients,
e_o365_mail_message_end_cc_recipients, known_recipients, NULL);
addr = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_BCC);
- o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_bcc_recipients,
e_o365_mail_message_end_bcc_recipients);
+ o365_utils_add_address_array (builder, addr, e_o365_mail_message_begin_bcc_recipients,
e_o365_mail_message_end_bcc_recipients, known_recipients, override_recipients);
+
+ if (known_recipients) {
+ g_hash_table_destroy (known_recipients);
+ known_recipients = NULL;
+ }
o365_utils_add_headers (builder, camel_medium_get_headers (CAMEL_MEDIUM (message)), &sender,
&request_read_receipt);
@@ -819,6 +877,8 @@ camel_o365_utils_create_message_sync (EO365Connection *cnc,
e_o365_mail_message_add_sender (builder, name, address);
g_clear_object (&sender);
+ } else if (override_from) {
+ /* Possibly force the Sender when the passed-in From doesn't match the account user address */
}
if (request_read_receipt)
@@ -867,6 +927,55 @@ camel_o365_utils_create_message_sync (EO365Connection *cnc,
if (info || is_send)
camel_o365_utils_add_message_flags (builder, info, is_send ? message : NULL);
+ if (out_attachments) {
+ *out_attachments = attachments;
+ } else if (attachments) {
+ GSList *link;
+
+ e_o365_json_begin_array_member (builder, "attachments");
+
+ for (link = attachments; link && success; link = g_slist_next (link)) {
+ CamelDataWrapper *dw = link->data;
+
+ o365_utils_add_attachment_object (builder, dw, cancellable);
+ }
+
+ e_o365_json_end_array_member (builder);
+
+ g_slist_free_full (attachments, g_object_unref);
+ }
+
+ return success;
+}
+
+gboolean
+camel_o365_utils_create_message_sync (EO365Connection *cnc,
+ const gchar *folder_id,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ gchar **out_appended_id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EO365MailMessage *appended_message = NULL;
+ GSList *attachments = NULL;
+ JsonBuilder *builder;
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), FALSE);
+
+ builder = json_builder_new_immutable ();
+
+ e_o365_json_begin_object_member (builder, NULL);
+
+ if (!camel_o365_utils_fill_message_object_sync (builder, message, info, NULL, NULL, FALSE,
&attachments, cancellable, error)) {
+ g_slist_free_full (attachments, g_object_unref);
+ g_object_unref (builder);
+
+ return FALSE;
+ }
+
e_o365_json_end_object_member (builder);
success = e_o365_connection_create_mail_message_sync (cnc, NULL, folder_id, builder,
&appended_message, cancellable, error);
@@ -881,28 +990,15 @@ camel_o365_utils_create_message_sync (EO365Connection *cnc,
message_id = e_o365_mail_message_get_id (appended_message);
- if (out_appended_uid)
- *out_appended_uid = g_strdup (message_id);
+ if (out_appended_id)
+ *out_appended_id = g_strdup (message_id);
for (link = attachments; link && success; link = g_slist_next (link)) {
CamelDataWrapper *dw = link->data;
- CamelContentType *ct;
-
- ct = camel_data_wrapper_get_mime_type_field (dw);
builder = json_builder_new_immutable ();
- e_o365_attachment_begin_attachment (builder, E_O365_ATTACHMENT_DATA_TYPE_FILE);
-
- if (camel_content_type_is (ct, "application", "x-pkcs7-mime") ||
- camel_content_type_is (ct, "application", "pkcs7-mime")) {
- o365_utils_add_smime_encrypted_attachment (builder, dw, cancellable);
- } else if (CAMEL_IS_MULTIPART_SIGNED (dw)) {
- o365_utils_add_smime_signed_attachment (builder, dw, cancellable);
- } else {
- o365_utils_add_file_attachment (builder, dw, cancellable);
- }
- e_o365_json_end_object_member (builder);
+ o365_utils_add_attachment_object (builder, dw, cancellable);
success = e_o365_connection_add_mail_message_attachment_sync (cnc, NULL, message_id,
builder, NULL, cancellable, error);
diff --git a/src/Office365/camel/camel-o365-utils.h b/src/Office365/camel/camel-o365-utils.h
index 3815c322..1cd109cd 100644
--- a/src/Office365/camel/camel-o365-utils.h
+++ b/src/Office365/camel/camel-o365-utils.h
@@ -37,13 +37,22 @@ void camel_o365_utils_add_message_flags
(JsonBuilder *builder,
CamelMessageInfo *info,
CamelMimeMessage *message);
+gboolean camel_o365_utils_fill_message_object_sync
+ (JsonBuilder *builder,
+ CamelMimeMessage *message,
+ CamelMessageInfo *info,
+ CamelAddress *override_from,
+ CamelAddress *override_recipients, /* it merges them, not
really override */
+ gboolean is_send,
+ GSList **out_attachments,
+ GCancellable *cancellable,
+ GError **error);
gboolean camel_o365_utils_create_message_sync
(EO365Connection *cnc,
const gchar *folder_id,
CamelMimeMessage *message,
CamelMessageInfo *info,
- gboolean is_send,
- gchar **out_appended_uid,
+ gchar **out_appended_id,
GCancellable *cancellable,
GError **error);
diff --git a/src/Office365/common/e-o365-connection.c b/src/Office365/common/e-o365-connection.c
index 9ceb2486..91e81161 100644
--- a/src/Office365/common/e-o365-connection.c
+++ b/src/Office365/common/e-o365-connection.c
@@ -3032,3 +3032,82 @@ e_o365_connection_delete_mail_messages_sync (EO365Connection *cnc,
return success;
}
+
+/* https://docs.microsoft.com/en-us/graph/api/message-send?view=graph-rest-1.0&tabs=http */
+
+gboolean
+e_o365_connection_send_mail_message_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the account
user */
+ const gchar *message_id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *message;
+ gboolean success;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (message_id != NULL, FALSE);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "messages",
+ message_id,
+ "send",
+ NULL);
+
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ soup_message_headers_append (message->request_headers, "Content-Length", "0");
+
+ success = o365_connection_send_request_sync (cnc, message, NULL, e_o365_read_no_response_cb, NULL,
cancellable, error);
+
+ g_clear_object (&message);
+
+ return success;
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http */
+
+gboolean
+e_o365_connection_send_mail_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the account user
*/
+ JsonBuilder *request, /* filled sendMail object */
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *message;
+ gboolean success;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (request != NULL, FALSE);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "sendMail", NULL, NULL, NULL);
+
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ e_o365_connection_set_json_body (message, request);
+
+ success = o365_connection_send_request_sync (cnc, message, NULL, e_o365_read_no_response_cb, NULL,
cancellable, error);
+
+ g_clear_object (&message);
+
+ return success;
+}
diff --git a/src/Office365/common/e-o365-connection.h b/src/Office365/common/e-o365-connection.h
index f8af1cfd..5174641f 100644
--- a/src/Office365/common/e-o365-connection.h
+++ b/src/Office365/common/e-o365-connection.h
@@ -281,6 +281,18 @@ gboolean e_o365_connection_delete_mail_messages_sync
GSList **out_deleted_ids, /* (transfer container): const
gchar *, borrowed from message_ids */
GCancellable *cancellable,
GError **error);
+gboolean e_o365_connection_send_mail_message_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *message_id,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_o365_connection_send_mail_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ JsonBuilder *request, /* filled sendMail object */
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]