summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2013-11-25 22:29:23 +0100
committerMilan Crha <mcrha@redhat.com>2013-11-25 22:31:36 +0100
commiteaf23db27e55eaeaf77a480b2f51512f090a7f76 (patch)
treead37d32393a5200a140406aa7054e78a8c125bf5
parent1b52c6fbc12a2f8df84b4618eb4c3db963a49989 (diff)
downloadevolution-data-server-eaf23db27e55eaeaf77a480b2f51512f090a7f76.tar.gz
Bug #680961 - Broken dispatching of EAuthenticationSession
There was basically no error reporting from the server to the client when any such occurred during authentication on the server side, thus the client was left waiting for a response which never happened. Even the 'dismiss' signal has a comment that it can be used for such cases, it's not the right thing to do, because it hides the errors from a user, thus he/she doesn't know that something went wrong. For that a new ServerError signal was added and the error is properly propagated to the client. Note the GOA errors don't strip the GDBus error from the message, which looks odd in the UI, thus I added a workaround for that too.
-rw-r--r--libebackend/e-authentication-mediator.c25
-rw-r--r--libebackend/e-authentication-mediator.h3
-rw-r--r--libebackend/e-source-registry-server.c11
-rw-r--r--libedataserver/e-source-registry.c25
-rw-r--r--modules/gnome-online-accounts/e-goa-password-based.c6
-rw-r--r--private/org.gnome.evolution.dataserver.Authenticator.xml15
6 files changed, 85 insertions, 0 deletions
diff --git a/libebackend/e-authentication-mediator.c b/libebackend/e-authentication-mediator.c
index 4a7e36fbe..af80a54f6 100644
--- a/libebackend/e-authentication-mediator.c
+++ b/libebackend/e-authentication-mediator.c
@@ -1264,3 +1264,28 @@ e_authentication_mediator_dismiss (EAuthenticationMediator *mediator)
e_dbus_authenticator_emit_dismissed (mediator->priv->interface);
}
+/**
+ * e_authentication_mediator_server_error:
+ * @mediator: an #EAuthenticationMediator
+ *
+ * Signals to the authentication client that the authentication session has
+ * terminated with a server-side error.
+ *
+ * Since: 3.12
+ **/
+void
+e_authentication_mediator_server_error (EAuthenticationMediator *mediator,
+ const GError *error)
+{
+ gchar *name;
+
+ g_return_if_fail (E_IS_AUTHENTICATION_MEDIATOR (mediator));
+ g_return_if_fail (error != NULL);
+
+ name = g_dbus_error_encode_gerror (error);
+ g_return_if_fail (name != NULL);
+
+ e_dbus_authenticator_emit_server_error (mediator->priv->interface, name, error->message);
+
+ g_free (name);
+}
diff --git a/libebackend/e-authentication-mediator.h b/libebackend/e-authentication-mediator.h
index f4c5e9c65..f0fe8e348 100644
--- a/libebackend/e-authentication-mediator.h
+++ b/libebackend/e-authentication-mediator.h
@@ -97,6 +97,9 @@ gboolean e_authentication_mediator_wait_for_client_finish
GError **error);
void e_authentication_mediator_dismiss
(EAuthenticationMediator *mediator);
+void e_authentication_mediator_server_error
+ (EAuthenticationMediator *mediator,
+ const GError *error);
G_END_DECLS
diff --git a/libebackend/e-source-registry-server.c b/libebackend/e-source-registry-server.c
index 6d39142a4..2e28fd0ee 100644
--- a/libebackend/e-source-registry-server.c
+++ b/libebackend/e-source-registry-server.c
@@ -492,8 +492,19 @@ source_registry_server_auth_session_cb (GObject *source_object,
session, result, &error);
if (error != NULL) {
+ ESourceAuthenticator *authenticator;
+
g_warn_if_fail (auth_result == E_AUTHENTICATION_SESSION_ERROR);
g_simple_async_result_take_error (request->simple, error);
+
+ /* If the authenticator is an EAuthenticationMediator,
+ * have it emit a "server-error" signal to the client. */
+ authenticator =
+ e_authentication_session_get_authenticator (session);
+ if (E_IS_AUTHENTICATION_MEDIATOR (authenticator))
+ e_authentication_mediator_server_error (
+ E_AUTHENTICATION_MEDIATOR (authenticator),
+ error);
}
/* Authentication dismissals require additional handling. */
diff --git a/libedataserver/e-source-registry.c b/libedataserver/e-source-registry.c
index 6589eb781..5ba6005f2 100644
--- a/libedataserver/e-source-registry.c
+++ b/libedataserver/e-source-registry.c
@@ -1884,6 +1884,26 @@ source_registry_authenticate_dismissed_cb (EDBusAuthenticator *dbus_auth,
}
/* Helper for e_source_registry_authenticate_sync() */
+static void
+source_registry_authenticate_server_error_cb (EDBusAuthenticator *dbus_auth,
+ const gchar *name,
+ const gchar *message,
+ AuthContext *auth_context)
+{
+ /* Be careful not to overwrite an existing error */
+ if (auth_context->auth_result != E_SOURCE_AUTHENTICATION_ERROR) {
+ GError *error;
+
+ error = g_dbus_error_new_for_dbus_error (name, message);
+ g_propagate_error (auth_context->error, error);
+
+ auth_context->auth_result = E_SOURCE_AUTHENTICATION_ERROR;
+ }
+
+ g_main_loop_quit (auth_context->main_loop);
+}
+
+/* Helper for e_source_registry_authenticate_sync() */
static gboolean
source_registry_call_authenticate_for_source (ESourceRegistry *registry,
ESourceAuthenticator *auth,
@@ -2071,6 +2091,11 @@ e_source_registry_authenticate_sync (ESourceRegistry *registry,
G_CALLBACK (source_registry_authenticate_dismissed_cb),
auth_context);
+ g_signal_connect (
+ dbus_auth, "server-error",
+ G_CALLBACK (source_registry_authenticate_server_error_cb),
+ auth_context);
+
encryption_key = gcr_secret_exchange_begin (
auth_context->secret_exchange);
diff --git a/modules/gnome-online-accounts/e-goa-password-based.c b/modules/gnome-online-accounts/e-goa-password-based.c
index 759d25823..827a6157c 100644
--- a/modules/gnome-online-accounts/e-goa-password-based.c
+++ b/modules/gnome-online-accounts/e-goa-password-based.c
@@ -116,6 +116,8 @@ e_goa_password_based_execute_sync (EAuthenticationSession *session,
goa_client = goa_client_new_sync (cancellable, error);
if (goa_client == NULL) {
session_result = E_AUTHENTICATION_SESSION_ERROR;
+ if (error && *error)
+ g_dbus_error_strip_remote_error (*error);
goto exit;
}
@@ -158,6 +160,8 @@ e_goa_password_based_execute_sync (EAuthenticationSession *session,
goa_account, NULL, cancellable, error);
if (!success) {
session_result = E_AUTHENTICATION_SESSION_ERROR;
+ if (error && *error)
+ g_dbus_error_strip_remote_error (*error);
goto exit;
}
@@ -185,6 +189,8 @@ e_goa_password_based_execute_sync (EAuthenticationSession *session,
if (password == NULL) {
session_result = E_AUTHENTICATION_SESSION_ERROR;
+ if (error && *error)
+ g_dbus_error_strip_remote_error (*error);
goto exit;
}
diff --git a/private/org.gnome.evolution.dataserver.Authenticator.xml b/private/org.gnome.evolution.dataserver.Authenticator.xml
index 4a17fb4c8..22d9a3474 100644
--- a/private/org.gnome.evolution.dataserver.Authenticator.xml
+++ b/private/org.gnome.evolution.dataserver.Authenticator.xml
@@ -91,5 +91,20 @@
-->
<signal name="Dismissed"/>
+ <!--
+ ServerError:
+ @name: a #GError name encoded with g_dbus_error_encode_gerror().
+ @message: a #GError::message
+
+ Emitted when there was a server-side error. A g_dbus_error_new_for_dbus_error()
+ can be used to reconstruct original #GError from @name and @message.
+
+ This signal ends the authentication session.
+ -->
+ <signal name="ServerError">
+ <arg name="name" type="s"/>
+ <arg name="message" type="s"/>
+ </signal>
+
</interface>