[evolution-data-server] ESoupSession: Extract common auth failure code into a utility function
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] ESoupSession: Extract common auth failure code into a utility function
- Date: Tue, 12 Jul 2022 13:52:12 +0000 (UTC)
commit 55fadda86fffe0121942913cd36eaf2febc6091e
Author: Milan Crha <mcrha redhat com>
Date: Tue Jul 12 15:47:39 2022 +0200
ESoupSession: Extract common auth failure code into a utility function
The code had been almost exactly the same with all the backends,
which use the ESoupSession or its derivatives. The added
e_soup_session_handle_authentication_failure() helps to avoid
the code duplication.
.../backends/carddav/e-book-backend-carddav.c | 48 ++----------
.../backends/caldav/e-cal-backend-caldav.c | 49 +++---------
.../backends/gtasks/e-cal-backend-gtasks.c | 47 +++--------
.../webdav-notes/e-cal-backend-webdav-notes.c | 49 +++---------
src/libedataserver/e-soup-session.c | 90 ++++++++++++++++++++--
src/libedataserver/e-soup-session.h | 8 ++
6 files changed, 124 insertions(+), 167 deletions(-)
---
diff --git a/src/addressbook/backends/carddav/e-book-backend-carddav.c
b/src/addressbook/backends/carddav/e-book-backend-carddav.c
index 19aa9802f..398e670d0 100644
--- a/src/addressbook/backends/carddav/e-book-backend-carddav.c
+++ b/src/addressbook/backends/carddav/e-book-backend-carddav.c
@@ -90,6 +90,8 @@ ebb_carddav_connect_sync (EBookMetaBackend *meta_backend,
g_return_val_if_fail (E_IS_BOOK_BACKEND_CARDDAV (meta_backend), FALSE);
g_return_val_if_fail (out_auth_result != NULL, FALSE);
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+
bbdav = E_BOOK_BACKEND_CARDDAV (meta_backend);
g_mutex_lock (&bbdav->priv->webdav_lock);
@@ -265,50 +267,14 @@ ebb_carddav_connect_sync (EBookMetaBackend *meta_backend,
}
if (success) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
} else {
- gboolean credentials_empty;
- gboolean is_tls_error = FALSE;
-
- credentials_empty = (!credentials || !e_named_parameters_count (credentials) ||
- (e_named_parameters_count (credentials) == 1 && e_named_parameters_exists
(credentials, E_SOURCE_CREDENTIAL_SSL_TRUST))) &&
- e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION (webdav));
- is_tls_error = g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
-
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
-
- /* because evolution knows only G_IO_ERROR_CANCELLED */
- if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_FORBIDDEN) &&
credentials_empty) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
- if (credentials_empty)
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- else
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
- (!e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION (webdav))
&&
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (!local_error) {
- g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error"));
- }
-
- if (local_error) {
- g_propagate_error (error, local_error);
- local_error = NULL;
- }
-
- if (is_tls_error) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
-
- e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED);
- e_soup_session_get_ssl_error_details (E_SOUP_SESSION (webdav), out_certificate_pem,
out_certificate_errors);
- } else {
- e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
- }
+ e_soup_session_handle_authentication_failure (E_SOUP_SESSION (webdav), credentials,
+ local_error, out_auth_result, out_certificate_pem, out_certificate_errors, error);
}
+ g_clear_error (&local_error);
+
if (capabilities)
g_hash_table_destroy (capabilities);
if (allows)
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index 63858d8f3..b3a77ca57 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -127,6 +127,8 @@ ecb_caldav_connect_sync (ECalMetaBackend *meta_backend,
g_return_val_if_fail (E_IS_CAL_BACKEND_CALDAV (meta_backend), FALSE);
g_return_val_if_fail (out_auth_result != NULL, FALSE);
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+
cbdav = E_CAL_BACKEND_CALDAV (meta_backend);
g_mutex_lock (&cbdav->priv->webdav_lock);
@@ -244,48 +246,15 @@ ecb_caldav_connect_sync (ECalMetaBackend *meta_backend,
g_free (ctag);
}
- if (!success) {
- gboolean credentials_empty;
- gboolean is_tls_error;
-
- credentials_empty = (!credentials || !e_named_parameters_count (credentials) ||
- (e_named_parameters_count (credentials) == 1 && e_named_parameters_exists
(credentials, E_SOURCE_CREDENTIAL_SSL_TRUST))) &&
- e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION (webdav));
- is_tls_error = g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
-
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
-
- if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_FORBIDDEN) &&
credentials_empty) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
- if (credentials_empty)
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- else
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
- (!e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION (webdav))
&&
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (!local_error) {
- g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error"));
- }
-
- if (local_error) {
- g_propagate_error (error, local_error);
- local_error = NULL;
- }
-
- if (is_tls_error) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
-
- e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED);
- e_soup_session_get_ssl_error_details (E_SOUP_SESSION (webdav), out_certificate_pem,
out_certificate_errors);
- } else {
- e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
- }
+ if (success) {
+ e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
+ } else {
+ e_soup_session_handle_authentication_failure (E_SOUP_SESSION (webdav), credentials,
+ local_error, out_auth_result, out_certificate_pem, out_certificate_errors, error);
}
+ g_clear_error (&local_error);
+
if (capabilities)
g_hash_table_destroy (capabilities);
if (allows)
diff --git a/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
b/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
index 971d825ca..28d358c7b 100644
--- a/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
+++ b/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
@@ -409,10 +409,10 @@ ecb_gtasks_connect_sync (ECalMetaBackend *meta_backend,
g_return_val_if_fail (E_IS_CAL_BACKEND_GTASKS (meta_backend), FALSE);
g_return_val_if_fail (out_auth_result != NULL, FALSE);
- cbgtasks = E_CAL_BACKEND_GTASKS (meta_backend);
-
*out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+ cbgtasks = E_CAL_BACKEND_GTASKS (meta_backend);
+
g_rec_mutex_lock (&cbgtasks->priv->conn_lock);
if (cbgtasks->priv->gdata &&
@@ -433,46 +433,17 @@ ecb_gtasks_connect_sync (ECalMetaBackend *meta_backend,
success = ecb_gtasks_prepare_tasklist_locked (cbgtasks, cancellable, &local_error);
- if (!success) {
- gboolean credentials_empty;
- gboolean is_tls_error;
-
- credentials_empty = (!credentials || !e_named_parameters_count (credentials) ||
- (e_named_parameters_count (credentials) == 1 && e_named_parameters_exists
(credentials, E_SOURCE_CREDENTIAL_SSL_TRUST))) &&
- e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION
(cbgtasks->priv->gdata));
- is_tls_error = g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
-
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
-
- if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_FORBIDDEN) &&
credentials_empty) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
- if (credentials_empty)
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- else
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
- (!e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION
(cbgtasks->priv->gdata)) &&
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (!local_error) {
- g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error");
- }
-
- if (local_error) {
- g_propagate_error (error, local_error);
- local_error = NULL;
- }
-
- if (is_tls_error) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
-
- e_soup_session_get_ssl_error_details (E_SOUP_SESSION (cbgtasks->priv->gdata),
out_certificate_pem, out_certificate_errors);
- }
+ if (success) {
+ e_source_set_connection_status (e_backend_get_source (E_BACKEND (cbgtasks)),
E_SOURCE_CONNECTION_STATUS_CONNECTED);
+ } else {
+ e_soup_session_handle_authentication_failure (E_SOUP_SESSION (cbgtasks->priv->gdata),
credentials,
+ local_error, out_auth_result, out_certificate_pem, out_certificate_errors, error);
}
g_rec_mutex_unlock (&cbgtasks->priv->conn_lock);
+ g_clear_error (&local_error);
+
return success;
}
diff --git a/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c
b/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c
index bd6146a87..83e04ed3d 100644
--- a/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c
+++ b/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c
@@ -118,6 +118,8 @@ ecb_webdav_notes_connect_sync (ECalMetaBackend *meta_backend,
g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE);
g_return_val_if_fail (out_auth_result != NULL, FALSE);
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+
cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend);
g_mutex_lock (&cbnotes->priv->webdav_lock);
@@ -205,48 +207,15 @@ ecb_webdav_notes_connect_sync (ECalMetaBackend *meta_backend,
g_free (ctag);
}
- if (!success) {
- gboolean credentials_empty;
- gboolean is_tls_error = FALSE;
-
- credentials_empty = (!credentials || !e_named_parameters_count (credentials) ||
- (e_named_parameters_count (credentials) == 1 && e_named_parameters_exists
(credentials, E_SOURCE_CREDENTIAL_SSL_TRUST))) &&
- e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION (webdav));
- is_tls_error = g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
-
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
-
- if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_FORBIDDEN) &&
credentials_empty) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
- if (credentials_empty)
- *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
- else
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
- (!e_soup_session_get_authentication_requires_credentials (E_SOUP_SESSION (webdav))
&&
- g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
- } else if (!local_error) {
- g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error"));
- }
-
- if (local_error) {
- g_propagate_error (error, local_error);
- local_error = NULL;
- }
-
- if (is_tls_error) {
- *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
-
- e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED);
- e_soup_session_get_ssl_error_details (E_SOUP_SESSION (webdav), out_certificate_pem,
out_certificate_errors);
- } else {
- e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
- }
+ if (success) {
+ e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
+ } else {
+ e_soup_session_handle_authentication_failure (E_SOUP_SESSION (webdav), credentials,
+ local_error, out_auth_result, out_certificate_pem, out_certificate_errors, error);
}
+ g_clear_error (&local_error);
+
if (capabilities)
g_hash_table_destroy (capabilities);
if (allows)
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index cb7a3bf05..289cda889 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -816,10 +816,10 @@ e_soup_session_get_authentication_requires_credentials (ESoupSession *session)
/**
* e_soup_session_get_ssl_error_details:
* @session: an #ESoupSession
- * @out_certificate_pem: (out): return location for a server TLS/SSL certificate
- * in PEM format, when the last operation failed with a TLS/SSL error
- * @out_certificate_errors: (out): return location for a #GTlsCertificateFlags,
- * with certificate error flags when the operation failed with a TLS/SSL error
+ * @out_certificate_pem: (out) (optional): return location for a server TLS/SSL certificate
+ * in PEM format, when the last operation failed with a TLS/SSL error, or %NULL
+ * @out_certificate_errors: (out) (optional): return location for a #GTlsCertificateFlags,
+ * with certificate error flags when the operation failed with a TLS/SSL error, or %NULL
*
* Populates @out_certificate_pem and @out_certificate_errors with the last values
* returned on #G_TLS_ERROR_BAD_CERTIFICATE error.
@@ -834,8 +834,6 @@ e_soup_session_get_ssl_error_details (ESoupSession *session,
GTlsCertificateFlags *out_certificate_errors)
{
g_return_val_if_fail (E_IS_SOUP_SESSION (session), FALSE);
- g_return_val_if_fail (out_certificate_pem != NULL, FALSE);
- g_return_val_if_fail (out_certificate_errors != NULL, FALSE);
g_mutex_lock (&session->priv->property_lock);
if (!session->priv->ssl_info_set) {
@@ -843,14 +841,90 @@ e_soup_session_get_ssl_error_details (ESoupSession *session,
return FALSE;
}
- *out_certificate_pem = g_strdup (session->priv->ssl_certificate_pem);
- *out_certificate_errors = session->priv->ssl_certificate_errors;
+ if (out_certificate_pem)
+ *out_certificate_pem = g_strdup (session->priv->ssl_certificate_pem);
+
+ if (out_certificate_errors)
+ *out_certificate_errors = session->priv->ssl_certificate_errors;
g_mutex_unlock (&session->priv->property_lock);
return TRUE;
}
+/**
+ * e_soup_session_handle_authentication_failure:
+ * @session: an #ESoupSession
+ * @credentials: (nullable): credentials used for the authentication
+ * @op_error: a #GError of the authentication operation
+ * @out_auth_result: (out): an #ESourceAuthenticationResult with an authentication result
+ * @out_certificate_pem: (out) (optional): return location for a server TLS/SSL certificate
+ * in PEM format, when the last operation failed with a TLS/SSL error, or %NULL
+ * @out_certificate_errors: (out) (optional): return location for a #GTlsCertificateFlags,
+ * with certificate error flags when the operation failed with a TLS/SSL error, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Handles authentication failure and sets appropriate value to the @out_auth_result
+ * for the provided @op_error and used @credentials. Converts the @op_error
+ * into an appropriate error returned in the @error.
+ *
+ * Also updates connection status on the associated #ESource with the @session.
+ *
+ * Since: 3.46
+ **/
+void
+e_soup_session_handle_authentication_failure (ESoupSession *session,
+ const ENamedParameters *credentials,
+ const GError *op_error,
+ ESourceAuthenticationResult *out_auth_result,
+ gchar **out_certificate_pem,
+ GTlsCertificateFlags *out_certificate_errors,
+ GError **error)
+{
+ ESource *source;
+ gboolean requires_credentials;
+ gboolean credentials_empty;
+ gboolean is_tls_error;
+
+ g_return_if_fail (E_IS_SOUP_SESSION (session));
+ g_return_if_fail (out_auth_result != NULL);
+
+ source = e_soup_session_get_source (session);
+ requires_credentials = e_soup_session_get_authentication_requires_credentials (session);
+ credentials_empty = (!credentials || !e_named_parameters_count (credentials) ||
+ (e_named_parameters_count (credentials) == 1 && e_named_parameters_exists (credentials,
E_SOURCE_CREDENTIAL_SSL_TRUST))) &&
+ requires_credentials;
+ is_tls_error = g_error_matches (op_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE);
+
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR;
+
+ if (g_error_matches (op_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_FORBIDDEN) && credentials_empty) {
+ *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
+ } else if (g_error_matches (op_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+ if (credentials_empty)
+ *out_auth_result = E_SOURCE_AUTHENTICATION_REQUIRED;
+ else
+ *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
+ } else if (g_error_matches (op_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
+ (!requires_credentials && g_error_matches (op_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))) {
+ *out_auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
+ } else if (!op_error) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Unknown error"));
+ }
+
+ if (op_error)
+ g_propagate_error (error, g_error_copy (op_error));
+
+ if (is_tls_error) {
+ *out_auth_result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
+
+ e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED);
+ e_soup_session_get_ssl_error_details (session, out_certificate_pem, out_certificate_errors);
+ } else {
+ e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
+ }
+}
+
static void
e_soup_session_preset_message (SoupMessage *message)
{
diff --git a/src/libedataserver/e-soup-session.h b/src/libedataserver/e-soup-session.h
index 28554ccc2..b5949b4b6 100644
--- a/src/libedataserver/e-soup-session.h
+++ b/src/libedataserver/e-soup-session.h
@@ -95,6 +95,14 @@ gboolean e_soup_session_get_authentication_requires_credentials
gboolean e_soup_session_get_ssl_error_details (ESoupSession *session,
gchar **out_certificate_pem,
GTlsCertificateFlags *out_certificate_errors);
+void e_soup_session_handle_authentication_failure
+ (ESoupSession *session,
+ const ENamedParameters *credentials,
+ const GError *op_error,
+ ESourceAuthenticationResult *out_auth_result,
+ gchar **out_certificate_pem,
+ GTlsCertificateFlags *out_certificate_errors,
+ GError **error);
SoupMessage * e_soup_session_new_message (ESoupSession *session,
const gchar *method,
const gchar *uri_string,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]