diff options
| author | Milan Crha <mcrha@redhat.com> | 2013-11-25 22:29:23 +0100 |
|---|---|---|
| committer | Milan Crha <mcrha@redhat.com> | 2013-11-25 22:31:36 +0100 |
| commit | eaf23db27e55eaeaf77a480b2f51512f090a7f76 (patch) | |
| tree | ad37d32393a5200a140406aa7054e78a8c125bf5 | |
| parent | 1b52c6fbc12a2f8df84b4618eb4c3db963a49989 (diff) | |
| download | evolution-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.c | 25 | ||||
| -rw-r--r-- | libebackend/e-authentication-mediator.h | 3 | ||||
| -rw-r--r-- | libebackend/e-source-registry-server.c | 11 | ||||
| -rw-r--r-- | libedataserver/e-source-registry.c | 25 | ||||
| -rw-r--r-- | modules/gnome-online-accounts/e-goa-password-based.c | 6 | ||||
| -rw-r--r-- | private/org.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 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> |
