]> git.0d.be Git - empathy.git/commitdiff
server-sasl-handler: make a GAsyncInitable and get the password
authorJonny Lamb <jonny.lamb@collabora.co.uk>
Mon, 6 Dec 2010 09:43:34 +0000 (09:43 +0000)
committerJonny Lamb <jonny.lamb@collabora.co.uk>
Mon, 6 Dec 2010 09:43:34 +0000 (09:43 +0000)
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
libempathy/empathy-auth-factory.c
libempathy/empathy-server-sasl-handler.c
libempathy/empathy-server-sasl-handler.h
src/empathy-auth-client.c

index 58b24dc4f8ed0b762891b1f2b59a11870cc793e4..578b6d6cd4e67253bf2916bb1d71c1d1922842b7 100644 (file)
@@ -129,6 +129,40 @@ sasl_handler_invalidated_cb (EmpathyServerSASLHandler *handler,
   tp_clear_object (&priv->sasl_handler);
 }
 
+static void
+server_sasl_handler_ready_cb (GObject *source,
+    GAsyncResult *res,
+    gpointer user_data)
+{
+  EmpathyAuthFactoryPriv *priv;
+  GError *error = NULL;
+  HandlerContextData *data = user_data;
+
+  priv = GET_PRIV (data->self);
+  priv->sasl_handler = empathy_server_sasl_handler_new_finish (res, &error);
+
+  if (error != NULL)
+    {
+      DEBUG ("Failed to create a server SASL handler; error %s",
+          error->message);
+      tp_handle_channels_context_fail (data->context, error);
+
+      g_error_free (error);
+    }
+  else
+    {
+      tp_handle_channels_context_accept (data->context);
+
+      g_signal_connect (priv->sasl_handler, "invalidated",
+          G_CALLBACK (sasl_handler_invalidated_cb), data->self);
+
+      g_signal_emit (data->self, signals[NEW_SERVER_SASL_HANDLER], 0,
+          priv->sasl_handler);
+    }
+
+  handler_context_data_free (data);
+}
+
 static void
 handle_channels_cb (TpSimpleHandler *handler,
     TpAccount *account,
@@ -210,28 +244,21 @@ handle_channels_cb (TpSimpleHandler *handler,
       goto error;
     }
 
+  data = handler_context_data_new (self, context);
+  tp_handle_channels_context_delay (context);
+
   /* create a handler */
   if (tp_channel_get_channel_type_id (channel) ==
       EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION)
     {
-      data = handler_context_data_new (self, context);
-      tp_handle_channels_context_delay (context);
-
       empathy_server_tls_handler_new_async (channel, server_tls_handler_ready_cb,
           data);
     }
   else if (tp_channel_get_channel_type_id (channel) ==
       TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
     {
-      priv->sasl_handler = empathy_server_sasl_handler_new (
-          account, channel);
-
-      g_signal_connect (priv->sasl_handler, "invalidated",
-          G_CALLBACK (sasl_handler_invalidated_cb), self);
-
-      tp_handle_channels_context_accept (context);
-      g_signal_emit (self, signals[NEW_SERVER_SASL_HANDLER], 0,
-          priv->sasl_handler);
+      empathy_server_sasl_handler_new_async (account, channel,
+          server_sasl_handler_ready_cb, data);
     }
   return;
 
index 9f10a7921a126ca419d1580b508235422492aee7..b71cbdb7b3c5d658f2518b8c7b5c45e0c7cab944 100644 (file)
@@ -24,6 +24,7 @@
 #define DEBUG_FLAG EMPATHY_DEBUG_SASL
 #include "empathy-debug.h"
 #include "empathy-utils.h"
+#include "empathy-keyring.h"
 
 enum {
   PROP_CHANNEL = 1,
@@ -44,10 +45,17 @@ typedef struct {
   TpAccount *account;
 
   GSimpleAsyncResult *result;
+
+  gchar *password;
+
+  GSimpleAsyncResult *async_init_res;
 } EmpathyServerSASLHandlerPriv;
 
-G_DEFINE_TYPE (EmpathyServerSASLHandler, empathy_server_sasl_handler,
-    G_TYPE_OBJECT);
+static void async_initable_iface_init (GAsyncInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EmpathyServerSASLHandler, empathy_server_sasl_handler,
+    G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init));
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerSASLHandler);
 
@@ -83,6 +91,83 @@ sasl_status_changed_cb (TpChannel *channel,
     }
 }
 
+static gboolean
+empathy_server_sasl_handler_give_password (gpointer data)
+{
+  EmpathyServerSASLHandler *self = data;
+  EmpathyServerSASLHandlerPriv *priv = GET_PRIV (self);
+
+  empathy_server_sasl_handler_provide_password (self,
+      priv->password, FALSE);
+
+  return FALSE;
+}
+
+static void
+empathy_server_sasl_handler_get_password_async_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  EmpathyServerSASLHandlerPriv *priv;
+  const gchar *password;
+  GError *error = NULL;
+
+  priv = GET_PRIV (user_data);
+
+  password = empathy_keyring_get_password_finish (TP_ACCOUNT (source),
+      result, &error);
+
+  if (password != NULL)
+    {
+      priv->password = g_strdup (password);
+
+      /* Do this in an idle so the async result will get there
+       * first. */
+      g_idle_add (empathy_server_sasl_handler_give_password, user_data);
+    }
+
+  g_simple_async_result_complete (priv->async_init_res);
+  tp_clear_object (&priv->async_init_res);
+}
+
+static void
+empathy_server_sasl_handler_init_async (GAsyncInitable *initable,
+    gint io_priority,
+    GCancellable *cancellable,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  EmpathyServerSASLHandler *self = EMPATHY_SERVER_SASL_HANDLER (initable);
+  EmpathyServerSASLHandlerPriv *priv = GET_PRIV (self);
+
+  g_assert (priv->account != NULL);
+
+  priv->async_init_res = g_simple_async_result_new (G_OBJECT (self),
+      callback, user_data, empathy_server_sasl_handler_new_async);
+
+  empathy_keyring_get_password_async (priv->account,
+      empathy_server_sasl_handler_get_password_async_cb, self);
+}
+
+static gboolean
+empathy_server_sasl_handler_init_finish (GAsyncInitable *initable,
+    GAsyncResult *res,
+    GError **error)
+{
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res),
+          error))
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *iface)
+{
+  iface->init_async = empathy_server_sasl_handler_init_async;
+  iface->init_finish = empathy_server_sasl_handler_init_finish;
+}
+
 static void
 channel_invalidated_cb (TpProxy *proxy,
     guint domain,
@@ -171,6 +256,18 @@ empathy_server_sasl_handler_dispose (GObject *object)
   G_OBJECT_CLASS (empathy_server_sasl_handler_parent_class)->dispose (object);
 }
 
+static void
+empathy_server_sasl_handler_finalize (GObject *object)
+{
+  EmpathyServerSASLHandlerPriv *priv = GET_PRIV (object);
+
+  DEBUG ("%p", object);
+
+  tp_clear_pointer (&priv->password, g_free);
+
+  G_OBJECT_CLASS (empathy_server_sasl_handler_parent_class)->finalize (object);
+}
+
 static void
 empathy_server_sasl_handler_class_init (EmpathyServerSASLHandlerClass *klass)
 {
@@ -181,6 +278,7 @@ empathy_server_sasl_handler_class_init (EmpathyServerSASLHandlerClass *klass)
   oclass->get_property = empathy_server_sasl_handler_get_property;
   oclass->set_property = empathy_server_sasl_handler_set_property;
   oclass->dispose = empathy_server_sasl_handler_dispose;
+  oclass->dispose = empathy_server_sasl_handler_finalize;
 
   g_type_class_add_private (klass, sizeof (EmpathyServerSASLHandlerPriv));
 
@@ -212,12 +310,35 @@ empathy_server_sasl_handler_init (EmpathyServerSASLHandler *self)
 }
 
 EmpathyServerSASLHandler *
-empathy_server_sasl_handler_new (TpAccount *account,
-    TpChannel *channel)
+empathy_server_sasl_handler_new_finish (GAsyncResult *result,
+    GError **error)
 {
-  g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
+  GObject *object, *source_object;
 
-  return g_object_new (EMPATHY_TYPE_SERVER_SASL_HANDLER,
+  source_object = g_async_result_get_source_object (result);
+
+  object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
+      result, error);
+  g_object_unref (source_object);
+
+  if (object != NULL)
+    return EMPATHY_SERVER_SASL_HANDLER (object);
+  else
+    return NULL;
+}
+
+void
+empathy_server_sasl_handler_new_async (TpAccount *account,
+    TpChannel *channel,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  g_return_if_fail (TP_IS_ACCOUNT (account));
+  g_return_if_fail (TP_IS_CHANNEL (channel));
+  g_return_if_fail (callback != NULL);
+
+  g_async_initable_new_async (EMPATHY_TYPE_SERVER_SASL_HANDLER,
+      G_PRIORITY_DEFAULT, NULL, callback, user_data,
       "account", account,
       "channel", channel,
       NULL);
@@ -300,3 +421,15 @@ empathy_server_sasl_handler_get_account (EmpathyServerSASLHandler *handler)
 
   return priv->account;
 }
+
+gboolean
+empathy_server_sasl_handler_has_password (EmpathyServerSASLHandler *handler)
+{
+  EmpathyServerSASLHandlerPriv *priv;
+
+  g_return_val_if_fail (EMPATHY_IS_SERVER_SASL_HANDLER (handler), FALSE);
+
+  priv = GET_PRIV (handler);
+
+  return (priv->password != NULL);
+}
index cdedef90c6f68f7874a8239544b080b91d408b01..1eedc5b27b38afcdfe6af1d5974ff8442815dc4f 100644 (file)
@@ -58,8 +58,12 @@ GType empathy_server_sasl_handler_get_type (void);
   (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_SERVER_SASL_HANDLER, \
   EmpathyServerSASLHandlerClass))
 
-EmpathyServerSASLHandler * empathy_server_sasl_handler_new (
-    TpAccount *account, TpChannel *channel);
+void empathy_server_sasl_handler_new_async (
+    TpAccount *account, TpChannel *channel,
+    GAsyncReadyCallback callback, gpointer user_data);
+
+EmpathyServerSASLHandler * empathy_server_sasl_handler_new_finish (
+    GAsyncResult *result, GError **error);
 
 void empathy_server_sasl_handler_provide_password (
     EmpathyServerSASLHandler *handler, const gchar *password,
@@ -70,6 +74,9 @@ void empathy_server_sasl_handler_cancel (EmpathyServerSASLHandler *handler);
 TpAccount * empathy_server_sasl_handler_get_account (
     EmpathyServerSASLHandler *handler);
 
+gboolean empathy_server_sasl_handler_has_password (
+    EmpathyServerSASLHandler *handler);
+
 G_END_DECLS
 
 #endif /* #ifndef __EMPATHY_SERVER_SASL_HANDLER_H__*/
index f6cc9def8a5f68acd724c48a982faf3c331434f6..98a736fb994ffe58da877cb8287a974038741034 100644 (file)
@@ -216,9 +216,12 @@ auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory,
 
   DEBUG ("New SASL server handler received from the factory");
 
-  /* TODO: check whether to show the dialog */
-  dialog = empathy_password_dialog_new (handler);
-  gtk_widget_show (dialog);
+  /* If the handler has the password it will deal with it itself. */
+  if (!empathy_server_sasl_handler_has_password (handler))
+    {
+      dialog = empathy_password_dialog_new (handler);
+      gtk_widget_show (dialog);
+    }
 }
 
 int