aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonny Lamb <jonnylamb@gnome.org>2010-12-08 20:01:53 +0800
committerJonny Lamb <jonnylamb@gnome.org>2011-01-26 21:32:05 +0800
commit734ec37772f59a96a581b54104e83b0d571c746e (patch)
treecd255cf475afbc2a546f6678625c7ac2de34dbe6
parentbaa5833e00509339a9c650d1f09db9932aa6a6cb (diff)
downloadgsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.tar
gsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.tar.gz
gsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.tar.bz2
gsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.tar.lz
gsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.tar.xz
gsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.tar.zst
gsoc2013-empathy-734ec37772f59a96a581b54104e83b0d571c746e.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.c168
1 files changed, 165 insertions, 3 deletions
diff --git a/libempathy/empathy-account-settings.c b/libempathy/empathy-account-settings.c
index 6e32568c5..fa2819097 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;