Skip to content

Commit

Permalink
[mcp-account-manager] Use libsignon to read credentials
Browse files Browse the repository at this point in the history
The authoritative source for an account's username is in its auth
credentials; manually storing that in the account as well can be
desynchronized and fail.

Instead, read the credentials from signon and set the telepathy account
name based on that. This still does involve mirroring the username to
an account setting, but it can be done in a reasonably automated way.

Currently, this only happens for account creation; it should be changed
in the near future to update as needed.
  • Loading branch information
John Brooks committed Dec 20, 2012
1 parent d2432d4 commit f99dcc0
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 35 deletions.
119 changes: 85 additions & 34 deletions mcp-account-manager-uoa/mcp-account-manager-uoa.c
Expand Up @@ -25,6 +25,9 @@
#include <libaccounts-glib/ag-account-service.h>
#include <libaccounts-glib/ag-manager.h>
#include <libaccounts-glib/ag-service.h>
#include <libaccounts-glib/ag-auth-data.h>

#include <libsignon-glib/signon-identity.h>

#include <string.h>
#include <ctype.h>
Expand Down Expand Up @@ -201,6 +204,8 @@ _service_enabled_cb (AgAccountService *service,
DEBUG ("UOA account %s toggled: %s", account_name,
enabled ? "enabled" : "disabled");

/* FIXME: Should this update the username from signon credentials first,
* in case that was changed? */
g_signal_emit_by_name (self, "toggled", account_name, enabled);

g_free (account_name);
Expand All @@ -217,6 +222,7 @@ _service_changed_cb (AgAccountService *service,

DEBUG ("UOA account %s changed", account_name);

/* FIXME: Should check signon credentials for changed username */
/* FIXME: Could use ag_account_service_get_changed_fields()
* and emit "altered-one" */
g_signal_emit_by_name (self, "altered", account_name);
Expand Down Expand Up @@ -262,6 +268,64 @@ _add_service (McpAccountManagerUoa *self,
return TRUE;
}

typedef struct
{
AgAccount *account;
AgAccountService *service;
McpAccountManagerUoa *self;
} AccountCreateData;

static void
_account_created_signon_cb(SignonIdentity *signon,
const SignonIdentityInfo *info,
const GError *error,
gpointer user_data)
{
AccountCreateData *data = (AccountCreateData*) user_data;
gchar *username = g_strdup (signon_identity_info_get_username (info));
gchar *account_name = NULL;

gchar *cm_name = _service_dup_tp_value (data->service, "manager");
gchar *protocol_name = _service_dup_tp_value (data->service, "protocol");

if (!tp_str_empty (cm_name) &&
!tp_str_empty (protocol_name) &&
!tp_str_empty (username))
{
GHashTable *params;

params = tp_asv_new (
"account", G_TYPE_STRING, username,
NULL);

account_name = mcp_account_manager_get_unique_name (data->self->priv->am,
cm_name, protocol_name, params);
_service_set_tp_account_name (data->service, account_name);

/* Must be stored for CMs */
_service_set_tp_value (data->service, "param-account", username);

ag_account_store (data->account, _account_stored_cb, data->self);

g_hash_table_unref (params);
}

g_free (cm_name);
g_free (protocol_name);

if (account_name != NULL)
{
if (_add_service (data->self, data->service, account_name))
g_signal_emit_by_name (data->self, "created", account_name);
}

g_free (account_name);
g_object_unref (data->service);
g_object_unref (data->account);
g_object_unref (signon);
g_free(data);
}

static void
_account_created_cb (AgManager *manager,
AgAccountId id,
Expand Down Expand Up @@ -289,52 +353,39 @@ _account_created_cb (AgManager *manager,
AgAccountService *service = ag_account_service_new (account, l->data);
gchar *account_name = _service_dup_tp_account_name (service);

ag_service_unref (l->data);
l = g_list_delete_link (l, l);

/* If this is the first time we see this service, we have to generate an
* account_name for it. */
if (account_name == NULL)
{
gchar *cm_name = NULL;
gchar *protocol_name = NULL;
gchar *account_param = NULL;

cm_name = _service_dup_tp_value (service, "manager");
protocol_name = _service_dup_tp_value (service, "protocol");
account_param = _service_dup_tp_value (service, "param-account");

if (!tp_str_empty (cm_name) &&
!tp_str_empty (protocol_name) &&
!tp_str_empty (account_param))
{
GHashTable *params;

params = tp_asv_new (
"account", G_TYPE_STRING, account_param,
NULL);

account_name = mcp_account_manager_get_unique_name (self->priv->am,
cm_name, protocol_name, params);
_service_set_tp_account_name (service, account_name);

ag_account_store (account, _account_stored_cb, self);

g_hash_table_unref (params);
}

g_free (cm_name);
g_free (protocol_name);
g_free (account_param);
/* Request auth data to get the username from signon; it's not available
* from the account. */
AgAuthData *auth_data = ag_account_service_get_auth_data (service);
guint cred_id = ag_auth_data_get_credentials_id (auth_data);
ag_auth_data_unref(auth_data);

SignonIdentity *signon = signon_identity_new_from_db (cred_id);

/* Callback frees/unrefs data */
AccountCreateData *data = g_new(AccountCreateData, 1);
data->account = account;
data->service = service;
data->self = self;

DEBUG("UOA querying account info from signon");
signon_identity_query_info(signon, _account_created_signon_cb, data);
return;
}

if (account_name != NULL)
else
{
if (_add_service (self, service, account_name))
g_signal_emit_by_name (self, "created", account_name);
}

g_free (account_name);
g_object_unref (service);
ag_service_unref (l->data);
l = g_list_delete_link (l, l);
}

g_object_unref (account);
Expand Down
2 changes: 1 addition & 1 deletion mcp-account-manager-uoa/mcp-account-manager-uoa.pro
Expand Up @@ -3,7 +3,7 @@ TARGET = mcp-account-manager-uoa

CONFIG += link_pkgconfig use_c_linker plugin no_plugin_name_prefix
CONFIG -= qt
PKGCONFIG += mission-control-plugins libaccounts-glib
PKGCONFIG += mission-control-plugins libaccounts-glib libsignon-glib

SOURCES = empathy-webcredentials-monitor.c \
mcp-account-manager-uoa.c \
Expand Down

0 comments on commit f99dcc0

Please sign in to comment.