[evolution-data-server] Bug #680961 - Broken dispatching of EAuthenticationSession



commit eaf23db27e55eaeaf77a480b2f51512f090a7f76
Author: Milan Crha <mcrha redhat com>
Date:   Mon Nov 25 22:29:23 2013 +0100

    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.

 libebackend/e-authentication-mediator.c            |   25 ++++++++++++++++++++
 libebackend/e-authentication-mediator.h            |    3 ++
 libebackend/e-source-registry-server.c             |   11 ++++++++
 libedataserver/e-source-registry.c                 |   25 ++++++++++++++++++++
 .../gnome-online-accounts/e-goa-password-based.c   |    6 ++++
 ...rg.gnome.evolution.dataserver.Authenticator.xml |   15 ++++++++++++
 6 files changed, 85 insertions(+), 0 deletions(-)
---
diff --git a/libebackend/e-authentication-mediator.c b/libebackend/e-authentication-mediator.c
index 4a7e36f..af80a54 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 f4c5e9c..f0fe8e3 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 6d39142..2e28fd0 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 6589eb7..5ba6005 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 759d258..827a615 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 4a17fb4..22d9a34 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>
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]