[evolution-ews/wip/mcrha/soup3] Make compile the m365 part (untested)
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/soup3] Make compile the m365 part (untested)
- Date: Wed, 5 Jan 2022 16:01:40 +0000 (UTC)
commit 7b7a41f994d1444dba80bbd0bb5524cfc1ff01df
Author: Milan Crha <mcrha redhat com>
Date: Wed Jan 5 17:01:08 2022 +0100
Make compile the m365 part (untested)
src/Microsoft365/camel/camel-m365-store.c | 7 +-
src/Microsoft365/common/e-m365-connection.c | 567 +++++-----------------------
src/Microsoft365/common/e-m365-connection.h | 15 +-
src/Microsoft365/registry/e-m365-backend.c | 4 +-
4 files changed, 110 insertions(+), 483 deletions(-)
---
diff --git a/src/Microsoft365/camel/camel-m365-store.c b/src/Microsoft365/camel/camel-m365-store.c
index a0f3f264..78ab2f31 100644
--- a/src/Microsoft365/camel/camel-m365-store.c
+++ b/src/Microsoft365/camel/camel-m365-store.c
@@ -198,7 +198,7 @@ m365_store_read_default_folders (CamelM365Store *m365_store,
message = soup_message_new (SOUP_METHOD_GET, uri);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"),
uri);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Malformed URI: “%s”"),
uri);
g_ptr_array_unref (requests);
g_free (uri);
@@ -222,7 +222,8 @@ m365_store_read_default_folders (CamelM365Store *m365_store,
SoupMessage *message = g_ptr_array_index (requests, ii);
JsonNode *node = NULL;
- if (message->status_code > 0 && SOUP_STATUS_IS_SUCCESSFUL (message->status_code) &&
+ if (e_m365_connection_util_get_message_status_code (message) > 0 &&
+ SOUP_STATUS_IS_SUCCESSFUL (e_m365_connection_util_get_message_status_code
(message)) &&
e_m365_connection_json_node_from_message (message, NULL, &node, cancellable,
NULL) &&
node && JSON_NODE_HOLDS_OBJECT (node)) {
JsonObject *object = json_node_get_object (node);
@@ -1809,7 +1810,7 @@ camel_m365_store_maybe_disconnect (CamelM365Store *m365_store,
if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
return;
- if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+ if (g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
CamelSession *session;
ESourceRegistry *registry = NULL;
diff --git a/src/Microsoft365/common/e-m365-connection.c b/src/Microsoft365/common/e-m365-connection.c
index 14f24cb8..226a55d7 100644
--- a/src/Microsoft365/common/e-m365-connection.c
+++ b/src/Microsoft365/common/e-m365-connection.c
@@ -33,15 +33,10 @@ struct _EM365ConnectionPrivate {
CamelM365Settings *settings;
SoupSession *soup_session;
GProxyResolver *proxy_resolver;
- ESoupAuthBearer *bearer_auth;
gchar *user; /* The default user for the URL */
gchar *impersonate_user;
- gboolean ssl_info_set;
- gchar *ssl_certificate_pem;
- GTlsCertificateFlags ssl_certificate_errors;
-
gchar *hash_key; /* in the opened connections hash */
/* How many microseconds to wait, until can execute a new request.
@@ -77,269 +72,6 @@ m365_log_enabled (void)
return log_enabled == 1;
}
-static SoupSession *
-m365_connection_ref_soup_session (EM365Connection *cnc)
-{
- SoupSession *soup_session = NULL;
-
- g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), NULL);
-
- LOCK (cnc);
-
- if (cnc->priv->soup_session)
- soup_session = g_object_ref (cnc->priv->soup_session);
-
- UNLOCK (cnc);
-
- return soup_session;
-}
-
-static void
-m365_connection_utils_ensure_bearer_auth_usage (SoupSession *session,
- SoupMessage *message,
- ESoupAuthBearer *bearer)
-{
- SoupAuthManager *auth_manager;
- SoupSessionFeature *feature;
- GUri *uri;
-
- g_return_if_fail (SOUP_IS_SESSION (session));
-
- /* Preload the SoupAuthManager with a valid "Bearer" token
- * when using OAuth 2.0. This avoids an extra unauthorized
- * HTTP round-trip, which apparently Google doesn't like. */
-
- feature = soup_session_get_feature (SOUP_SESSION (session), SOUP_TYPE_AUTH_MANAGER);
-
- if (!soup_session_feature_has_feature (feature, E_TYPE_SOUP_AUTH_BEARER)) {
- /* Add the "Bearer" auth type to support OAuth 2.0. */
- soup_session_feature_add_feature (feature, E_TYPE_SOUP_AUTH_BEARER);
- }
-
- uri = message ? soup_message_get_uri (message) : NULL;
- if (uri && g_uri_get_host (uri) && *g_uri_get_host (uri)) {
- uri = g_uri_build (G_URI_FLAGS_PARSE_RELAXED,
- g_uri_get_scheme (uri),
- NULL /* userinfo */,
- g_uri_get_host (uri),
- g_uri_get_port (uri),
- NULL /* path */,
- NULL /* query */,
- NULL /* fragment */);
- } else {
- uri = NULL;
- }
-
- g_return_if_fail (uri != NULL);
-
- auth_manager = SOUP_AUTH_MANAGER (feature);
-
- /* This will make sure the 'bearer' is used regardless of the current 'auth_manager' state.
- See https://gitlab.gnome.org/GNOME/libsoup/-/issues/196 for more information. */
- soup_auth_manager_clear_cached_credentials (auth_manager);
- soup_auth_manager_use_auth (auth_manager, uri, SOUP_AUTH (bearer));
-
- g_uri_unref (uri);
-}
-
-static gboolean
-m365_connection_utils_setup_bearer_auth (EM365Connection *cnc,
- SoupSession *session,
- SoupMessage *message,
- gboolean is_in_authenticate_handler,
- ESoupAuthBearer *bearer,
- GCancellable *cancellable,
- GError **error)
-{
- ESource *source;
- gchar *access_token = NULL;
- gint expires_in_seconds = -1;
- gboolean success = FALSE;
-
- g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
- g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (bearer), FALSE);
-
- source = e_m365_connection_get_source (cnc);
-
- success = e_source_get_oauth2_access_token_sync (source, cancellable,
- &access_token, &expires_in_seconds, error);
-
- if (success) {
- e_soup_auth_bearer_set_access_token (bearer, access_token, expires_in_seconds);
-
- if (!is_in_authenticate_handler) {
- if (session)
- g_object_ref (session);
- else
- session = m365_connection_ref_soup_session (cnc);
-
- m365_connection_utils_ensure_bearer_auth_usage (session, message, bearer);
-
- g_clear_object (&session);
- }
- }
-
- g_free (access_token);
-
- return success;
-}
-
-static gboolean
-m365_connection_utils_prepare_bearer_auth (EM365Connection *cnc,
- SoupSession *session,
- SoupMessage *message,
- GCancellable *cancellable)
-{
- ESource *source;
- ESoupAuthBearer *using_bearer_auth;
- gboolean success;
- GError *local_error = NULL;
-
- g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-
- source = e_m365_connection_get_source (cnc);
- if (!source)
- return TRUE;
-
- using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
- if (using_bearer_auth) {
- success = m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE,
using_bearer_auth, cancellable, &local_error);
- g_clear_object (&using_bearer_auth);
- } else {
- SoupAuth *soup_auth;
- GUri *uri;
-
- uri = message ? soup_message_get_uri (message) : NULL;
- if (uri && g_uri_get_host (uri) && *g_uri_get_host (uri)) {
- uri = g_uri_build (G_URI_FLAGS_PARSE_RELAXED,
- g_uri_get_scheme (uri),
- NULL /* userinfo */,
- g_uri_get_host (uri),
- g_uri_get_port (uri),
- NULL /* path */,
- NULL /* query */,
- NULL /* fragment */);
- } else {
- uri = NULL;
- }
-
- g_warn_if_fail (uri != NULL);
-
- if (!uri) {
- soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, "Cannot get host from
message");
- return FALSE;
- }
-
- soup_auth = g_object_new (E_TYPE_SOUP_AUTH_BEARER, SOUP_AUTH_HOST, g_uri_get_host (uri),
NULL);
-
- success = m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE,
E_SOUP_AUTH_BEARER (soup_auth), cancellable, &local_error);
- if (success)
- e_m365_connection_set_bearer_auth (cnc, E_SOUP_AUTH_BEARER (soup_auth));
-
- g_object_unref (soup_auth);
- g_uri_unref (uri);
- }
-
- if (!success) {
- if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- soup_message_set_status (message, SOUP_STATUS_CANCELLED);
- else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- soup_message_set_status_full (message, SOUP_STATUS_UNAUTHORIZED,
local_error->message);
- else
- soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, local_error ?
local_error->message : _("Unknown error"));
- }
-
- g_clear_error (&local_error);
-
- return success;
-}
-
-static gboolean
-m365_connection_authenticate (SoupMessage *msg,
- SoupAuth *auth,
- gboolean retrying,
- gpointer user_data)
-{
- EM365Connection *cnc = user_data;
- ESoupAuthBearer *using_bearer_auth;
- GError *local_error = NULL;
-
- g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), TRUE);
-
- using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-
- if (E_IS_SOUP_AUTH_BEARER (auth)) {
- g_object_ref (auth);
- g_warn_if_fail ((gpointer) using_bearer_auth == (gpointer) auth);
-
- g_clear_object (&using_bearer_auth);
- using_bearer_auth = E_SOUP_AUTH_BEARER (auth);
-
- e_m365_connection_set_bearer_auth (cnc, using_bearer_auth);
- }
-
- if (!using_bearer_auth) {
- g_warn_if_reached ();
- return TRUE;
- }
-
- m365_connection_utils_setup_bearer_auth (cnc, cnc->priv->soup_session, msg, TRUE, E_SOUP_AUTH_BEARER
(auth), NULL, &local_error);
-
- if (local_error)
- soup_message_set_status_full (msg, SOUP_STATUS_IO_ERROR, local_error->message);
-
- g_object_unref (using_bearer_auth);
- g_clear_error (&local_error);
-
- return TRUE;
-}
-
-static gboolean
-m365_connection_utils_prepare_message (EM365Connection *cnc,
- SoupSession *session,
- SoupMessage *message,
- GCancellable *cancellable)
-{
- ESoupAuthBearer *using_bearer_auth;
- ESource *source;
- GError *local_error = NULL;
-
- source = e_m365_connection_get_source (cnc);
- if (source)
- e_soup_ssl_trust_connect (message, source);
-
- if (!g_signal_handler_find (message, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL,
m365_connection_authenticate, cnc)) {
- g_signal_connect (
- message, "authenticate",
- G_CALLBACK (m365_connection_authenticate), cnc);
- }
-
- if (!m365_connection_utils_prepare_bearer_auth (cnc, session, message, cancellable))
- return FALSE;
-
- using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-
- if (using_bearer_auth &&
- e_soup_auth_bearer_is_expired (using_bearer_auth) &&
- !m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, using_bearer_auth,
cancellable, &local_error)) {
- if (local_error) {
- soup_message_set_status_full (message, SOUP_STATUS_BAD_REQUEST, local_error->message);
- g_clear_error (&local_error);
- } else {
- soup_message_set_status (message, SOUP_STATUS_BAD_REQUEST);
- }
-
- g_object_unref (using_bearer_auth);
-
- return FALSE;
- }
-
- g_clear_object (&using_bearer_auth);
-
- return TRUE;
-}
-
static void
m365_connection_set_settings (EM365Connection *cnc,
CamelM365Settings *settings)
@@ -536,6 +268,8 @@ m365_connection_constructed (GObject *object)
/* Chain up to parent's method. */
G_OBJECT_CLASS (e_m365_connection_parent_class)->constructed (object);
+ cnc->priv->soup_session = SOUP_SESSION (e_soup_session_new (cnc->priv->source));
+
if (m365_log_enabled ()) {
SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY);
@@ -546,13 +280,23 @@ m365_connection_constructed (GObject *object)
soup_session_add_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_COOKIE_JAR);
soup_session_add_feature_by_type (cnc->priv->soup_session, E_TYPE_SOUP_AUTH_BEARER);
+
+ /* This can use only OAuth2 authentication, which should be set on the ESource */
soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_BASIC);
+ soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_NTLM);
+ soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_NEGOTIATE);
+ soup_session_add_feature_by_type (cnc->priv->soup_session, E_TYPE_SOUP_AUTH_BEARER);
cnc->priv->hash_key = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (cnc->priv->settings));
if (!cnc->priv->hash_key)
cnc->priv->hash_key = g_strdup ("no-user");
+ e_binding_bind_property (
+ cnc, "proxy-resolver",
+ cnc->priv->soup_session, "proxy-resolver",
+ G_BINDING_SYNC_CREATE);
+
e_binding_bind_property (
cnc->priv->settings, "timeout",
cnc->priv->soup_session, "timeout",
@@ -580,17 +324,10 @@ m365_connection_dispose (GObject *object)
LOCK (cnc);
- if (cnc->priv->soup_session) {
- g_signal_handlers_disconnect_by_func (
- cnc->priv->soup_session,
- m365_connection_authenticate, object);
- }
-
g_clear_object (&cnc->priv->source);
g_clear_object (&cnc->priv->settings);
g_clear_object (&cnc->priv->soup_session);
g_clear_object (&cnc->priv->proxy_resolver);
- g_clear_object (&cnc->priv->bearer_auth);
UNLOCK (cnc);
@@ -604,7 +341,6 @@ m365_connection_finalize (GObject *object)
EM365Connection *cnc = E_M365_CONNECTION (object);
g_rec_mutex_clear (&cnc->priv->property_lock);
- g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
g_clear_pointer (&cnc->priv->user, g_free);
g_clear_pointer (&cnc->priv->impersonate_user, g_free);
g_free (cnc->priv->hash_key);
@@ -717,22 +453,38 @@ e_m365_connection_init (EM365Connection *cnc)
g_rec_mutex_init (&cnc->priv->property_lock);
cnc->priv->backoff_for_usec = 0;
- cnc->priv->soup_session = soup_session_new_with_options (
- "timeout", 90,
- NULL);
-
- /* Do not use G_BINDING_SYNC_CREATE, because we don't have a GProxyResolver yet anyway. */
- e_binding_bind_property (
- cnc, "proxy-resolver",
- cnc->priv->soup_session, "proxy-resolver",
- G_BINDING_DEFAULT);
}
gboolean
e_m365_connection_util_delta_token_failed (const GError *error)
{
- return g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
- g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_BAD_REQUEST);
+ return g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
+ g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_BAD_REQUEST);
+}
+
+void
+e_m365_connection_util_set_message_status_code (SoupMessage *message,
+ gint status_code)
+{
+ g_return_if_fail (SOUP_IS_MESSAGE (message));
+
+ g_object_set_data (G_OBJECT (message), "m365-batch-status-code",
+ GINT_TO_POINTER (status_code));
+}
+
+gint
+e_m365_connection_util_get_message_status_code (SoupMessage *message)
+{
+ gint status_code;
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (message), -1);
+
+ status_code = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (message), "m365-batch-status-code"));
+
+ if (!status_code)
+ status_code = soup_message_get_status (message);
+
+ return status_code;
}
EM365Connection *
@@ -854,7 +606,7 @@ e_m365_connection_get_concurrent_connections (EM365Connection *cnc)
LOCK (cnc);
- g_object_get (G_OBJECT (cnc->priv->soup_session), SOUP_SESSION_MAX_CONNS, ¤t_cc, NULL);
+ g_object_get (G_OBJECT (cnc->priv->soup_session), "max-conns", ¤t_cc, NULL);
UNLOCK (cnc);
@@ -879,8 +631,8 @@ e_m365_connection_set_concurrent_connections (EM365Connection *cnc,
LOCK (cnc);
g_object_set (G_OBJECT (cnc->priv->soup_session),
- SOUP_SESSION_MAX_CONNS, concurrent_connections,
- SOUP_SESSION_MAX_CONNS_PER_HOST, concurrent_connections,
+ "max-conns", concurrent_connections,
+ "max-conns-per-host", concurrent_connections,
NULL);
UNLOCK (cnc);
@@ -935,43 +687,6 @@ e_m365_connection_set_proxy_resolver (EM365Connection *cnc,
g_object_notify (G_OBJECT (cnc), "proxy-resolver");
}
-ESoupAuthBearer *
-e_m365_connection_ref_bearer_auth (EM365Connection *cnc)
-{
- ESoupAuthBearer *res = NULL;
-
- g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), NULL);
-
- LOCK (cnc);
-
- if (cnc->priv->bearer_auth)
- res = g_object_ref (cnc->priv->bearer_auth);
-
- UNLOCK (cnc);
-
- return res;
-}
-
-void
-e_m365_connection_set_bearer_auth (EM365Connection *cnc,
- ESoupAuthBearer *bearer_auth)
-{
- g_return_if_fail (E_IS_M365_CONNECTION (cnc));
-
- LOCK (cnc);
-
- if (cnc->priv->bearer_auth != bearer_auth) {
- g_clear_object (&cnc->priv->bearer_auth);
-
- cnc->priv->bearer_auth = bearer_auth;
-
- if (cnc->priv->bearer_auth)
- g_object_ref (cnc->priv->bearer_auth);
- }
-
- UNLOCK (cnc);
-}
-
static void
m365_connection_request_cancelled_cb (GCancellable *cancellable,
gpointer user_data)
@@ -983,35 +698,6 @@ m365_connection_request_cancelled_cb (GCancellable *cancellable,
e_flag_set (flag);
}
-static void
-m365_connection_extract_ssl_data (EM365Connection *cnc,
- SoupMessage *message)
-{
- GTlsCertificate *certificate = NULL;
-
- g_return_if_fail (E_IS_M365_CONNECTION (cnc));
- g_return_if_fail (SOUP_IS_MESSAGE (message));
-
- LOCK (cnc);
-
- g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
- cnc->priv->ssl_info_set = FALSE;
-
- g_object_get (G_OBJECT (message),
- "tls-certificate", &certificate,
- "tls-errors", &cnc->priv->ssl_certificate_errors,
- NULL);
-
- if (certificate) {
- g_object_get (certificate, "certificate-pem", &cnc->priv->ssl_certificate_pem, NULL);
- cnc->priv->ssl_info_set = TRUE;
-
- g_object_unref (certificate);
- }
-
- UNLOCK (cnc);
-}
-
/* An example error response:
{
@@ -1032,6 +718,7 @@ m365_connection_extract_error (JsonNode *node,
GError **error)
{
JsonObject *object;
+ GQuark domain = E_SOUP_SESSION_ERROR;
const gchar *code, *message;
if (!node || !JSON_NODE_HOLDS_OBJECT (node))
@@ -1048,15 +735,17 @@ m365_connection_extract_error (JsonNode *node,
if (!code && !message)
return FALSE;
- if (!status_code || SOUP_STATUS_IS_SUCCESSFUL (status_code))
- status_code = SOUP_STATUS_MALFORMED;
- else if (g_strcmp0 (code, "ErrorInvalidUser") == 0)
+ if (!status_code || status_code == -1 || SOUP_STATUS_IS_SUCCESSFUL (status_code)) {
+ domain = G_IO_ERROR;
+ status_code = G_IO_ERROR_INVALID_DATA;
+ } else if (g_strcmp0 (code, "ErrorInvalidUser") == 0) {
status_code = SOUP_STATUS_UNAUTHORIZED;
+ }
if (code && message)
- g_set_error (error, SOUP_HTTP_ERROR, status_code, "%s: %s", code, message);
+ g_set_error (error, domain, status_code, "%s: %s", code, message);
else
- g_set_error_literal (error, SOUP_HTTP_ERROR, status_code, code ? code : message);
+ g_set_error_literal (error, domain, status_code, code ? code : message);
return TRUE;
}
@@ -1093,7 +782,7 @@ e_m365_connection_json_node_from_message (SoupMessage *message,
if (message_json_object) {
*out_node = json_node_init_object (json_node_new (JSON_NODE_OBJECT), message_json_object);
- success = !m365_connection_extract_error (*out_node, message->status_code, &local_error);
+ success = !m365_connection_extract_error (*out_node,
e_m365_connection_util_get_message_status_code (message), &local_error);
} else {
const gchar *content_type;
@@ -1108,24 +797,15 @@ e_m365_connection_json_node_from_message (SoupMessage *message,
if (input_stream) {
success = json_parser_load_from_stream (json_parser, input_stream,
cancellable, error);
} else {
- SoupBuffer *sbuffer;
-
- sbuffer = soup_message_body_flatten (message->response_body);
-
- if (sbuffer) {
- success = json_parser_load_from_data (json_parser, sbuffer->data,
sbuffer->length, error);
- soup_buffer_free (sbuffer);
- } else {
- /* This should not happen, it's for safety check only, thus the
string is not localized */
- success = FALSE;
- g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "No
JSON data found");
- }
+ /* This should not happen, it's for safety check only, thus the string is not
localized */
+ success = FALSE;
+ g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "No JSON
data found");
}
if (success) {
*out_node = json_parser_steal_root (json_parser);
- success = !m365_connection_extract_error (*out_node, message->status_code,
&local_error);
+ success = !m365_connection_extract_error (*out_node,
e_m365_connection_util_get_message_status_code (message), &local_error);
}
g_object_unref (json_parser);
@@ -1229,37 +909,27 @@ m365_connection_send_request_sync (EM365Connection *cnc,
if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
UNLOCK (cnc);
- soup_message_set_status (message, SOUP_STATUS_CANCELLED);
+ e_m365_connection_util_set_message_status_code (message, -1);
return FALSE;
}
soup_session = cnc->priv->soup_session ? g_object_ref (cnc->priv->soup_session) : NULL;
- g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
- cnc->priv->ssl_certificate_errors = 0;
- cnc->priv->ssl_info_set = FALSE;
-
UNLOCK (cnc);
- if (soup_session &&
- m365_connection_utils_prepare_message (cnc, soup_session, message, cancellable)) {
+ if (soup_session) {
GInputStream *input_stream;
- input_stream = soup_session_send (soup_session, message, cancellable, error);
+ input_stream = e_soup_session_send_message_sync (E_SOUP_SESSION (soup_session),
message, cancellable, error);
success = input_stream != NULL;
- if (success && m365_log_enabled ())
- input_stream = e_soup_logger_attach (message, input_stream);
-
/* Throttling - https://docs.microsoft.com/en-us/graph/throttling */
- if (message->status_code == 429 ||
+ if (e_m365_connection_util_get_message_status_code (message) == 429 ||
/*
https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
- message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE) {
+ e_m365_connection_util_get_message_status_code (message) ==
SOUP_STATUS_SERVICE_UNAVAILABLE) {
need_retry = TRUE;
- } else if (message->status_code == SOUP_STATUS_SSL_FAILED) {
- m365_connection_extract_ssl_data (cnc, message);
}
if (need_retry) {
@@ -1284,13 +954,13 @@ m365_connection_send_request_sync (EM365Connection *cnc,
if (cnc->priv->backoff_for_usec < need_retry_seconds * G_USEC_PER_SEC)
cnc->priv->backoff_for_usec = need_retry_seconds * G_USEC_PER_SEC;
- if (message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE)
+ if (e_m365_connection_util_get_message_status_code (message) ==
SOUP_STATUS_SERVICE_UNAVAILABLE)
soup_session_abort (soup_session);
UNLOCK (cnc);
success = FALSE;
- } else if (success && raw_data_func && SOUP_STATUS_IS_SUCCESSFUL
(message->status_code)) {
+ } else if (success && raw_data_func && SOUP_STATUS_IS_SUCCESSFUL
(e_m365_connection_util_get_message_status_code (message))) {
success = raw_data_func (cnc, message, input_stream, func_user_data,
cancellable, error);
} else if (success) {
JsonNode *node = NULL;
@@ -1319,14 +989,13 @@ m365_connection_send_request_sync (EM365Connection *cnc,
}
g_free (next_link);
- } else if (error && !*error && message->status_code &&
!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
- if (message->status_code == SOUP_STATUS_CANCELLED) {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- message->reason_phrase ? message->reason_phrase :
soup_status_get_phrase (message->status_code));
- } else {
- g_set_error_literal (error, SOUP_HTTP_ERROR,
message->status_code,
- message->reason_phrase ? message->reason_phrase :
soup_status_get_phrase (message->status_code));
- }
+ } else if (error && !*error && e_m365_connection_util_get_message_status_code
(message) && !SOUP_STATUS_IS_SUCCESSFUL (e_m365_connection_util_get_message_status_code (message))) {
+ if (e_m365_connection_util_get_message_status_code (message) == -1)
+ g_set_error_literal (error, G_IO_ERROR,
G_IO_ERROR_INVALID_DATA, _("Invalid data"));
+ else
+ g_set_error_literal (error, E_SOUP_SESSION_ERROR,
e_m365_connection_util_get_message_status_code (message),
+ soup_message_get_reason_phrase (message) ?
soup_message_get_reason_phrase (message) :
+ soup_status_get_phrase
(e_m365_connection_util_get_message_status_code (message)));
}
if (node)
@@ -1335,15 +1004,14 @@ m365_connection_send_request_sync (EM365Connection *cnc,
g_clear_object (&input_stream);
} else {
- if (!message->status_code)
- soup_message_set_status (message, SOUP_STATUS_CANCELLED);
-
- if (message->status_code == SOUP_STATUS_CANCELLED) {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- message->reason_phrase ? message->reason_phrase :
soup_status_get_phrase (message->status_code));
+ if (!e_m365_connection_util_get_message_status_code (message)) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation
was cancelled"));
+ } else if (e_m365_connection_util_get_message_status_code (message) == -1) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Invalid
data"));
} else {
- g_set_error_literal (error, SOUP_HTTP_ERROR, message->status_code,
- message->reason_phrase ? message->reason_phrase :
soup_status_get_phrase (message->status_code));
+ g_set_error_literal (error, E_SOUP_SESSION_ERROR,
e_m365_connection_util_get_message_status_code (message),
+ soup_message_get_reason_phrase (message) ?
soup_message_get_reason_phrase (message) :
+ soup_status_get_phrase
(e_m365_connection_util_get_message_status_code (message)));
}
}
@@ -1537,36 +1205,12 @@ m365_connection_new_soup_message (const gchar *method,
if ((csm_flags & CSM_DISABLE_RESPONSE) != 0)
soup_message_headers_append (request_headers, "Prefer", "return=minimal");
} else {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Malformed URI: “%s”"), uri);
}
return message;
}
-gboolean
-e_m365_connection_get_ssl_error_details (EM365Connection *cnc,
- gchar **out_certificate_pem,
- GTlsCertificateFlags *out_certificate_errors)
-{
- g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
- g_return_val_if_fail (out_certificate_pem != NULL, FALSE);
- g_return_val_if_fail (out_certificate_errors != NULL, FALSE);
-
- LOCK (cnc);
-
- if (!cnc->priv->ssl_info_set) {
- UNLOCK (cnc);
- return FALSE;
- }
-
- *out_certificate_pem = g_strdup (cnc->priv->ssl_certificate_pem);
- *out_certificate_errors = cnc->priv->ssl_certificate_errors;
-
- UNLOCK (cnc);
-
- return TRUE;
-}
-
ESourceAuthenticationResult
e_m365_connection_authenticate_sync (EM365Connection *cnc,
const gchar *user_override,
@@ -1619,35 +1263,22 @@ e_m365_connection_authenticate_sync (EM365Connection *cnc,
if (success) {
result = E_SOURCE_AUTHENTICATION_ACCEPTED;
} else {
- if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_CANCELLED)) {
- local_error->domain = G_IO_ERROR;
- local_error->code = G_IO_ERROR_CANCELLED;
- } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ /* Nothing to do */
+ } else if (e_soup_session_get_ssl_error_details (E_SOUP_SESSION (cnc->priv->soup_session),
out_certificate_pem, out_certificate_errors)) {
result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
+ } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+ LOCK (cnc);
- if (out_certificate_pem || out_certificate_errors)
- e_m365_connection_get_ssl_error_details (cnc, out_certificate_pem,
out_certificate_errors);
- } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
- ESoupAuthBearer *bearer;
-
- bearer = e_m365_connection_ref_bearer_auth (cnc);
-
- if (bearer) {
- LOCK (cnc);
-
- if (cnc->priv->impersonate_user) {
- g_propagate_error (error, local_error);
- local_error = NULL;
- } else {
- result = E_SOURCE_AUTHENTICATION_REJECTED;
- }
-
- UNLOCK (cnc);
+ if (cnc->priv->impersonate_user) {
+ g_propagate_error (error, local_error);
+ local_error = NULL;
} else {
- result = E_SOURCE_AUTHENTICATION_REQUIRED;
+ result = E_SOURCE_AUTHENTICATION_REJECTED;
}
- g_clear_object (&bearer);
+ UNLOCK (cnc);
+
g_clear_error (&local_error);
}
@@ -1741,7 +1372,7 @@ e_m365_connection_construct_uri (EM365Connection *cnc,
if (use_user) {
gchar *encoded;
- encoded = soup_uri_encode (use_user, NULL);
+ encoded = g_uri_escape_string (use_user, NULL, FALSE);
g_string_append_c (uri, '/');
g_string_append (uri, encoded);
@@ -1785,7 +1416,7 @@ e_m365_connection_construct_uri (EM365Connection *cnc,
if (*value) {
gchar *encoded;
- encoded = soup_uri_encode (value, NULL);
+ encoded = g_uri_escape_string (value, NULL, FALSE);
g_string_append (uri, encoded);
@@ -1866,7 +1497,7 @@ e_m365_connection_fill_batch_response (SoupMessage *message,
g_return_if_fail (SOUP_IS_MESSAGE (message));
g_return_if_fail (object != NULL);
- message->status_code = e_m365_json_get_int_member (object, "status", SOUP_STATUS_MALFORMED);
+ e_m365_connection_util_set_message_status_code (message, e_m365_json_get_int_member (object,
"status", -1));
subobject = e_m365_json_get_object_member (object, "headers");
@@ -1989,13 +1620,13 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
if (!submessage)
continue;
- submessage->status_code = SOUP_STATUS_IO_ERROR;
+ e_m365_connection_util_set_message_status_code (submessage, -1);
guri = soup_message_get_uri (submessage);
uri = guri ? g_uri_to_string_partial (guri, G_URI_HIDE_PASSWORD) : NULL;
if (!uri) {
- submessage->status_code = SOUP_STATUS_MALFORMED;
+ g_warning ("%s: Batch message ignored due to no URI", G_STRFUNC);
continue;
}
@@ -2011,7 +1642,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
e_m365_json_begin_object_member (builder, NULL);
e_m365_json_add_string_member (builder, "id", buff);
- e_m365_json_add_string_member (builder, "method", submessage->method);
+ e_m365_json_add_string_member (builder, "method", soup_message_get_method (submessage));
e_m365_json_add_string_member (builder, "url", use_uri);
g_free (uri);
@@ -2049,7 +1680,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
parser = json_parser_new_immutable ();
- success = json_parser_load_from_stream (parser, request_body, error);
+ success = json_parser_load_from_stream (parser, request_body, cancellable,
error);
if (!success)
g_prefix_error (error, "%s", _("Failed to parse own Json data"));
@@ -2071,7 +1702,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
buffer = g_new0 (guint8, n_buffer_sz);
array = g_byte_array_sized_new (request_body_length + 1);
- while (g_input_stream_read_all (request_body, buffer, n_buffer_sz, &n_read,
cancellable, NULL))) {
+ while (g_input_stream_read_all (request_body, buffer, n_buffer_sz, &n_read,
cancellable, NULL)) {
if (n_read > 0)
g_byte_array_append (array, buffer, n_read);
}
@@ -2080,7 +1711,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
buffer[0] = '\0';
g_byte_array_append (array, buffer, 1);
- e_m365_json_add_string_member (builder, "body", array->data);
+ e_m365_json_add_string_member (builder, "body", (const gchar *) array->data);
g_byte_array_unref (array);
g_free (buffer);
@@ -2145,9 +1776,9 @@ e_m365_connection_batch_request_sync (EM365Connection *cnc,
continue;
/* Throttling - https://docs.microsoft.com/en-us/graph/throttling */
- if (message->status_code == 429 ||
+ if (e_m365_connection_util_get_message_status_code (message) == 429 ||
/*
https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
- message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE) {
+ e_m365_connection_util_get_message_status_code (message) ==
SOUP_STATUS_SERVICE_UNAVAILABLE) {
const gchar *retry_after_str;
gint64 retry_after;
diff --git a/src/Microsoft365/common/e-m365-connection.h b/src/Microsoft365/common/e-m365-connection.h
index e12a18be..89cee114 100644
--- a/src/Microsoft365/common/e-m365-connection.h
+++ b/src/Microsoft365/common/e-m365-connection.h
@@ -76,6 +76,11 @@ struct _EM365ConnectionClass {
gboolean e_m365_connection_util_delta_token_failed
(const GError *error);
+void e_m365_connection_util_set_message_status_code
+ (SoupMessage *message,
+ gint status_code);
+gint e_m365_connection_util_get_message_status_code
+ (SoupMessage *message);
GType e_m365_connection_get_type (void) G_GNUC_CONST;
@@ -105,16 +110,6 @@ GProxyResolver *e_m365_connection_ref_proxy_resolver
void e_m365_connection_set_proxy_resolver
(EM365Connection *cnc,
GProxyResolver *proxy_resolver);
-ESoupAuthBearer *
- e_m365_connection_ref_bearer_auth
- (EM365Connection *cnc);
-void e_m365_connection_set_bearer_auth
- (EM365Connection *cnc,
- ESoupAuthBearer *bearer_auth);
-gboolean e_m365_connection_get_ssl_error_details
- (EM365Connection *cnc,
- gchar **out_certificate_pem,
- GTlsCertificateFlags *out_certificate_errors);
ESourceAuthenticationResult
e_m365_connection_authenticate_sync
(EM365Connection *cnc,
diff --git a/src/Microsoft365/registry/e-m365-backend.c b/src/Microsoft365/registry/e-m365-backend.c
index a19917b0..e8bb3580 100644
--- a/src/Microsoft365/registry/e-m365-backend.c
+++ b/src/Microsoft365/registry/e-m365-backend.c
@@ -344,8 +344,8 @@ m365_backend_sync_contact_folders_sync (EM365Backend *m365_backend,
id, NULL, display_name, TRUE, NULL);
json_object_unref (user_contacts);
- } else if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_NOT_FOUND) ||
- g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+ } else if (g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_NOT_FOUND) ||
+ g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
m365_backend_remove_resource (m365_backend, E_SOURCE_EXTENSION_ADDRESS_BOOK, NULL);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]