aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonny Lamb <jonnylamb@gnome.org>2010-12-08 20:01:53 +0800
committerJonny Lamb <jonnylamb@gnome.org>2010-12-08 20:01:53 +0800
commit5f2776557174cf952c465c9b13960238574c8481 (patch)
tree41bb9ed6dfa0d7e32a611977f980146d290082d6
parentb1a60391b1ca744b3bd5c3218488ccd4cab9b86c (diff)
downloadgsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.tar
gsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.tar.gz
gsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.tar.bz2
gsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.tar.lz
gsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.tar.xz
gsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.tar.zst
gsoc2013-empathy-5f2776557174cf952c465c9b13960238574c8481.zip
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>
-rw-r--r--libempathy/empathy-account-settings.c164
1 files changed, 161 insertions, 3 deletions
diff --git a/libempathy/empathy-account-settings.c b/libempathy/empathy-account-settings.c
index c5c1be8b1..abfc8f0ec 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"
@@ -70,6 +71,15 @@ 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;
/* Keys are parameter names from the hash above (gchar *).
@@ -373,6 +383,8 @@ empathy_account_settings_finalize (GObject *object)
g_free (priv->service);
g_free (priv->display_name);
g_free (priv->icon_name);
+ g_free (priv->password);
+ g_free (priv->password_original);
if (priv->required_params != NULL)
{
@@ -409,6 +421,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);
@@ -485,6 +530,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");
@@ -745,6 +809,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);
@@ -758,14 +830,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))
@@ -960,7 +1042,16 @@ empathy_account_settings_set_string (EmpathyAccountSettings *settings,
g_return_if_fail (param != NULL);
g_return_if_fail (value != NULL);
- tp_asv_set_string (priv->parameters, g_strdup (param), value);
+ 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);
}
@@ -1196,6 +1287,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)
@@ -1210,12 +1350,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;