[empathy/gnome-2-34: 28/60] account-settings: add support for saving the password in the keyring ourselves



commit 734ec37772f59a96a581b54104e83b0d571c746e
Author: Jonny Lamb <jonnylamb gnome org>
Date:   Wed Dec 8 12:01:53 2010 +0000

    account-settings: add support for saving the password in the keyring ourselves
    
    Only do this if the CM supports popping up SASL-enabled auth channels.
    
    Signed-off-by: Jonny Lamb <jonnylamb gnome org>

 libempathy/empathy-account-settings.c |  168 ++++++++++++++++++++++++++++++++-
 1 files changed, 165 insertions(+), 3 deletions(-)
---
diff --git a/libempathy/empathy-account-settings.c b/libempathy/empathy-account-settings.c
index 6e32568..fa28190 100644
--- a/libempathy/empathy-account-settings.c
+++ b/libempathy/empathy-account-settings.c
@@ -29,6 +29,7 @@
 
 #include "empathy-account-settings.h"
 #include "empathy-connection-managers.h"
+#include "empathy-keyring.h"
 #include "empathy-utils.h"
 #include "empathy-idle.h"
 
@@ -68,6 +69,16 @@ struct _EmpathyAccountSettingsPriv
   gboolean display_name_overridden;
   gboolean ready;
 
+  gboolean supports_sasl;
+  gboolean password_changed;
+
+  gchar *password;
+  gchar *password_original;
+
+  gboolean password_retrieved;
+  gboolean password_requested;
+
+  /* Parameter name (gchar *) -> parameter value (GValue) */
   GHashTable *parameters;
   GArray *unset_parameters;
   GArray *required_params;
@@ -337,6 +348,8 @@ empathy_account_settings_finalize (GObject *object)
   g_free (priv->protocol);
   g_free (priv->display_name);
   g_free (priv->icon_name);
+  g_free (priv->password);
+  g_free (priv->password_original);
 
   if (priv->required_params != NULL)
     g_array_free (priv->required_params, TRUE);
@@ -368,6 +381,39 @@ empathy_account_settings_protocol_obj_prepared_cb (GObject *source,
 }
 
 static void
+empathy_account_settings_get_password_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  EmpathyAccountSettings *self = user_data;
+  EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
+  const gchar *password;
+  GError *error = NULL;
+
+  password = empathy_keyring_get_password_finish (TP_ACCOUNT (source),
+      result, &error);
+
+  if (error != NULL)
+    {
+      DEBUG ("Failed to get password: %s", error->message);
+      g_clear_error (&error);
+    }
+
+  /* It doesn't really matter if getting the password failed; that
+   * just means that it's not there, or let's act like that at
+   * least. */
+
+  g_assert (priv->password == NULL);
+
+  priv->password = g_strdup (password);
+  priv->password_original = g_strdup (password);
+
+  priv->password_retrieved = TRUE;
+
+  empathy_account_settings_check_readyness (self);
+}
+
+static void
 empathy_account_settings_check_readyness (EmpathyAccountSettings *self)
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
@@ -447,6 +493,25 @@ empathy_account_settings_check_readyness (EmpathyAccountSettings *self)
           empathy_account_settings_protocol_obj_prepared_cb, self);
       return;
     }
+  else
+    {
+      if (tp_strv_contains (tp_protocol_get_authentication_types (
+                  priv->protocol_obj),
+              TP_IFACE_CHANNEL_INTERFACE_SASL_AUTHENTICATION))
+        {
+          priv->supports_sasl = TRUE;
+        }
+    }
+
+  if (priv->supports_sasl && !priv->password_retrieved
+      && !priv->password_requested)
+    {
+      priv->password_requested = TRUE;
+
+      empathy_keyring_get_password_async (priv->account,
+          empathy_account_settings_get_password_cb, self);
+      return;
+    }
 
   priv->ready = TRUE;
   g_object_notify (G_OBJECT (self), "ready");
@@ -697,6 +762,14 @@ empathy_account_settings_unset (EmpathyAccountSettings *settings,
   if (empathy_account_settings_is_unset (settings, param))
     return;
 
+  if (priv->supports_sasl && !tp_strdiff (param, "password"))
+    {
+      g_free (priv->password);
+      priv->password = NULL;
+      priv->password_changed = TRUE;
+      return;
+    }
+
   v = g_strdup (param);
 
   g_array_append_val (priv->unset_parameters, v);
@@ -710,14 +783,24 @@ empathy_account_settings_discard_changes (EmpathyAccountSettings *settings)
 
   g_hash_table_remove_all (priv->parameters);
   empathy_account_settings_free_unset_parameters (settings);
+
+  priv->password_changed = FALSE;
+  g_free (priv->password);
+  priv->password = g_strdup (priv->password_original);
 }
 
 const gchar *
 empathy_account_settings_get_string (EmpathyAccountSettings *settings,
     const gchar *param)
 {
+  EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
   const GValue *v;
 
+  if (!tp_strdiff (param, "password") && priv->supports_sasl)
+    {
+      return priv->password;
+    }
+
   v = empathy_account_settings_get (settings, param);
 
   if (v == NULL || !G_VALUE_HOLDS_STRING (v))
@@ -909,7 +992,19 @@ empathy_account_settings_set_string (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
-  tp_asv_set_string (priv->parameters, g_strdup (param), value);
+  g_return_if_fail (param != NULL);
+  g_return_if_fail (value != NULL);
+
+  if (!tp_strdiff (param, "password") && priv->supports_sasl)
+    {
+      g_free (priv->password);
+      priv->password = g_strdup (value);
+      priv->password_changed = TRUE;
+    }
+  else
+    {
+      tp_asv_set_string (priv->parameters, g_strdup (param), value);
+    }
 
   account_settings_remove_from_unset (settings, param);
 }
@@ -1128,6 +1223,55 @@ empathy_account_settings_set_icon_name_finish (
 }
 
 static void
+empathy_account_settings_processed_password (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data,
+    gpointer finish_func)
+{
+  EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (user_data);
+  EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
+  GSimpleAsyncResult *r;
+  GError *error = NULL;
+  gboolean (*func) (TpAccount *source, GAsyncResult *result, GError **error) =
+    finish_func;
+
+  g_free (priv->password_original);
+  priv->password_original = g_strdup (priv->password);
+
+  if (!func (TP_ACCOUNT (source), result, &error))
+    {
+      g_simple_async_result_set_from_error (priv->apply_result, error);
+      g_error_free (error);
+    }
+
+  empathy_account_settings_discard_changes (settings);
+
+  r = priv->apply_result;
+  priv->apply_result = NULL;
+
+  g_simple_async_result_complete (r);
+  g_object_unref (r);
+}
+
+static void
+empathy_account_settings_set_password_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  empathy_account_settings_processed_password (source, result, user_data,
+      empathy_keyring_set_password_finish);
+}
+
+static void
+empathy_account_settings_delete_password_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  empathy_account_settings_processed_password (source, result, user_data,
+      empathy_keyring_delete_password_finish);
+}
+
+static void
 empathy_account_settings_account_updated (GObject *source,
     GAsyncResult *result,
     gpointer user_data)
@@ -1142,12 +1286,30 @@ empathy_account_settings_account_updated (GObject *source,
     {
       g_simple_async_result_set_from_error (priv->apply_result, error);
       g_error_free (error);
+      goto out;
     }
-  else
+
+  /* Only set the password in the keyring if the CM supports SASL and
+   * it's changed. */
+  if (priv->supports_sasl && priv->password_changed)
     {
-      empathy_account_settings_discard_changes (settings);
+      if (priv->password != NULL)
+        {
+          empathy_keyring_set_password_async (priv->account, priv->password,
+              empathy_account_settings_set_password_cb, settings);
+        }
+      else
+        {
+          empathy_keyring_delete_password_async (priv->account,
+              empathy_account_settings_delete_password_cb, settings);
+        }
+
+      return;
     }
 
+out:
+  empathy_account_settings_discard_changes (settings);
+
   r = priv->apply_result;
   priv->apply_result = NULL;
 



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