[gnome-online-accounts] daemon: Store the credentials in the keyring inside AddAccount
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts] daemon: Store the credentials in the keyring inside AddAccount
- Date: Tue, 19 Jun 2012 21:32:29 +0000 (UTC)
commit f4a707046a2640c340f6787211ec79f0c8994e66
Author: Debarshi Ray <debarshir gnome org>
Date: Tue Jun 19 23:19:07 2012 +0200
daemon: Store the credentials in the keyring inside AddAccount
A new argument of type a{sv} was added to the AddAccount method for
passing the credentials to the daemon. This is an API break, but no
should be calling it apart from the backend code implementing
goa_provider_add_account.
This fixes a race between the "account-added" signal being emitted and
the credentials being actually stored.
data/dbus-interfaces.xml | 2 +
src/daemon/goadaemon.c | 52 ++++++++++++++++++++++++++--
src/goabackend/goaexchangeprovider.c | 41 ++++++++++------------
src/goabackend/goaoauth2provider.c | 58 +++++++++++++++-----------------
src/goabackend/goaoauthprovider.c | 62 ++++++++++++++++------------------
src/goabackend/goautils.c | 38 +++++++++++++++------
src/goabackend/goautils.h | 16 ++++++---
7 files changed, 163 insertions(+), 106 deletions(-)
---
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml
index 61d7cd3..48ad569 100644
--- a/data/dbus-interfaces.xml
+++ b/data/dbus-interfaces.xml
@@ -284,6 +284,7 @@
@provider: The account provider. See the #org.gnome.OnlineAccounts.Account:ProviderType property for known providers.
@identity: The identity of the account (cf. the #org.gnome.OnlineAccounts.Account:Identity property).
@presentation_identity: The identity of the account that is suitable for display in an user interface (cf. the #org.gnome.OnlineAccounts.Account:PresentationIdentity property).
+ @credentials: The credentials to store.
@details: Extra key/value pairs to set.
@account_object_path: The object path of the created account.
@@ -294,6 +295,7 @@
<arg name="provider" type="s" direction="in"/>
<arg name="identity" type="s" direction="in"/>
<arg name="presentation_identity" type="s" direction="in"/>
+ <arg name="credentials" type="a{sv}" direction="in"/>
<arg name="details" type="a{ss}" direction="in"/>
<arg name="account_object_path" type="o" direction="out"/>
</method>
diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c
index 6975029..e1098ed 100644
--- a/src/daemon/goadaemon.c
+++ b/src/daemon/goadaemon.c
@@ -63,9 +63,10 @@ static void on_file_monitor_changed (GFileMonitor *monitor,
static gboolean on_manager_handle_add_account (GoaManager *object,
GDBusMethodInvocation *invocation,
- const gchar *provider,
+ const gchar *provider_type,
const gchar *identity,
const gchar *presentation_identity,
+ GVariant *credentials,
GVariant *details,
gpointer user_data);
@@ -684,15 +685,19 @@ generate_new_id (GoaDaemon *daemon)
static gboolean
on_manager_handle_add_account (GoaManager *manager,
GDBusMethodInvocation *invocation,
- const gchar *provider,
+ const gchar *provider_type,
const gchar *identity,
const gchar *presentation_identity,
+ GVariant *credentials,
GVariant *details,
gpointer user_data)
{
GoaDaemon *daemon = GOA_DAEMON (user_data);
+ GoaProvider *provider;
GKeyFile *key_file;
GError *error;
+ GList *providers;
+ GList *l;
gchar *path;
gchar *id;
gchar *group;
@@ -705,7 +710,9 @@ on_manager_handle_add_account (GoaManager *manager,
/* TODO: could check for @type */
+ provider = NULL;
key_file = NULL;
+ providers = NULL;
path = NULL;
id = NULL;
group = NULL;
@@ -747,7 +754,7 @@ on_manager_handle_add_account (GoaManager *manager,
id = generate_new_id (daemon);
group = g_strdup_printf ("Account %s", id);
- g_key_file_set_string (key_file, group, "Provider", provider);
+ g_key_file_set_string (key_file, group, "Provider", provider_type);
g_key_file_set_string (key_file, group, "Identity", identity);
g_key_file_set_string (key_file, group, "PresentationIdentity", presentation_identity);
@@ -780,6 +787,43 @@ on_manager_handle_add_account (GoaManager *manager,
goto out;
}
+ providers = goa_provider_get_all ();
+ for (l = providers; l != NULL; l = l->next)
+ {
+ GoaProvider *p;
+ const gchar *type;
+
+ p = GOA_PROVIDER (l->data);
+ type = goa_provider_get_provider_type (p);
+ if (g_strcmp0 (type, provider_type) == 0)
+ {
+ provider = p;
+ break;
+ }
+ }
+
+ if (provider == NULL)
+ {
+ error= NULL;
+ g_set_error (&error,
+ GOA_ERROR,
+ GOA_ERROR_FAILED, /* TODO: more specific */
+ _("Failed to find a provider for: %s"),
+ provider_type);
+ g_dbus_method_invocation_return_gerror (invocation, error);
+ goto out;
+ }
+
+ if (!goa_utils_store_credentials_for_id_sync (provider,
+ id,
+ credentials,
+ NULL, /* GCancellable */
+ &error))
+ {
+ g_dbus_method_invocation_return_gerror (invocation, error);
+ goto out;
+ }
+
goa_daemon_reload_configuration (daemon);
object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id);
@@ -787,6 +831,8 @@ on_manager_handle_add_account (GoaManager *manager,
out:
g_free (object_path);
+ if (providers != NULL)
+ g_list_free_full (providers, g_object_unref);
g_free (data);
g_free (group);
g_free (id);
diff --git a/src/goabackend/goaexchangeprovider.c b/src/goabackend/goaexchangeprovider.c
index 963d0e8..7473bc2 100644
--- a/src/goabackend/goaexchangeprovider.c
+++ b/src/goabackend/goaexchangeprovider.c
@@ -564,7 +564,8 @@ add_account (GoaProvider *provider,
GError **error)
{
AddAccountData data;
- GVariantBuilder builder;
+ GVariantBuilder credentials;
+ GVariantBuilder details;
GoaEwsClient *ews_client;
GoaObject *ret;
const gchar *email_address;
@@ -649,22 +650,26 @@ add_account (GoaProvider *provider,
gtk_widget_hide (GTK_WIDGET (dialog));
+ g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&credentials, "{sv}", "password", g_variant_new_string (password));
+
+ g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
+ g_variant_builder_add (&details, "{ss}", "MailEnabled", "true");
+ g_variant_builder_add (&details, "{ss}", "CalendarEnabled", "true");
+ g_variant_builder_add (&details, "{ss}", "ContactsEnabled", "true");
+ g_variant_builder_add (&details, "{ss}", "Host", server);
+
/* OK, everything is dandy, add the account */
/* we want the GoaClient to update before this method returns (so it
* can create a proxy for the new object) so run the mainloop while
* waiting for this to complete
*/
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
- g_variant_builder_add (&builder, "{ss}", "MailEnabled", "true");
- g_variant_builder_add (&builder, "{ss}", "CalendarEnabled", "true");
- g_variant_builder_add (&builder, "{ss}", "ContactsEnabled", "true");
- g_variant_builder_add (&builder, "{ss}", "Host", server);
-
goa_manager_call_add_account (goa_client_get_manager (client),
goa_provider_get_provider_type (provider),
username,
email_address,
- g_variant_builder_end (&builder),
+ g_variant_builder_end (&credentials),
+ g_variant_builder_end (&details),
NULL, /* GCancellable* */
(GAsyncReadyCallback) add_account_cb,
&data);
@@ -674,16 +679,6 @@ add_account (GoaProvider *provider,
ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
data.account_object_path));
- /* TODO: run in worker thread */
- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
- g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password));
-
- if (!goa_utils_store_credentials_sync (provider,
- ret,
- g_variant_builder_end (&builder),
- NULL, /* GCancellable */
- &data.error))
- goto out;
out:
/* We might have an object even when data.error is set.
@@ -815,11 +810,11 @@ refresh_account (GoaProvider *provider,
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password));
- if (!goa_utils_store_credentials_sync (provider,
- object,
- g_variant_builder_end (&builder),
- NULL, /* GCancellable */
- error))
+ if (!goa_utils_store_credentials_for_object_sync (provider,
+ object,
+ g_variant_builder_end (&builder),
+ NULL, /* GCancellable */
+ error))
goto out;
goa_account_call_ensure_credentials (account,
diff --git a/src/goabackend/goaoauth2provider.c b/src/goabackend/goaoauth2provider.c
index fbf998f..a895f6e 100644
--- a/src/goabackend/goaoauth2provider.c
+++ b/src/goabackend/goaoauth2provider.c
@@ -1036,7 +1036,8 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
gchar *identity;
gchar *presentation_identity;
AddData data;
- GVariantBuilder builder;
+ GVariantBuilder credentials;
+ GVariantBuilder details;
g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (provider), NULL);
g_return_val_if_fail (GOA_IS_CLIENT (client), NULL);
@@ -1077,17 +1078,29 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
&data.error))
goto out;
+ g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
+ if (authorization_code != NULL)
+ g_variant_builder_add (&credentials, "{sv}", "authorization_code", g_variant_new_string (authorization_code));
+ g_variant_builder_add (&credentials, "{sv}", "access_token", g_variant_new_string (access_token));
+ if (access_token_expires_in > 0)
+ g_variant_builder_add (&credentials, "{sv}", "access_token_expires_at",
+ g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
+ if (refresh_token != NULL)
+ g_variant_builder_add (&credentials, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
+
+ g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
+ goa_oauth2_provider_add_account_key_values (provider, &details);
+
/* we want the GoaClient to update before this method returns (so it
* can create a proxy for the new object) so run the mainloop while
* waiting for this to complete
*/
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
- goa_oauth2_provider_add_account_key_values (provider, &builder);
goa_manager_call_add_account (goa_client_get_manager (client),
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
identity,
presentation_identity,
- g_variant_builder_end (&builder),
+ g_variant_builder_end (&credentials),
+ g_variant_builder_end (&details),
NULL, /* GCancellable* */
(GAsyncReadyCallback) add_account_cb,
&data);
@@ -1098,23 +1111,6 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
data.account_object_path));
- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
- if (authorization_code != NULL)
- g_variant_builder_add (&builder, "{sv}", "authorization_code", g_variant_new_string (authorization_code));
- g_variant_builder_add (&builder, "{sv}", "access_token", g_variant_new_string (access_token));
- if (access_token_expires_in > 0)
- g_variant_builder_add (&builder, "{sv}", "access_token_expires_at",
- g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
- if (refresh_token != NULL)
- g_variant_builder_add (&builder, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
- /* TODO: run in worker thread */
- if (!goa_utils_store_credentials_sync (GOA_PROVIDER (provider),
- ret,
- g_variant_builder_end (&builder),
- NULL, /* GCancellable */
- &data.error))
- goto out;
-
out:
/* We might have an object even when data.error is set.
* eg., if we failed to store the credentials in the keyring.
@@ -1209,11 +1205,11 @@ goa_oauth2_provider_refresh_account (GoaProvider *_provider,
g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
if (refresh_token != NULL)
g_variant_builder_add (&builder, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
- if (!goa_utils_store_credentials_sync (GOA_PROVIDER (provider),
- object,
- g_variant_builder_end (&builder),
- NULL, /* GCancellable */
- error))
+ if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
+ object,
+ g_variant_builder_end (&builder),
+ NULL, /* GCancellable */
+ error))
goto out;
goa_account_call_ensure_credentials (goa_object_peek_account (object),
@@ -1426,11 +1422,11 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
if (refresh_token != NULL)
g_variant_builder_add (&builder, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
- if (!goa_utils_store_credentials_sync (GOA_PROVIDER (provider),
- object,
- g_variant_builder_end (&builder),
- cancellable,
- error))
+ if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
+ object,
+ g_variant_builder_end (&builder),
+ cancellable,
+ error))
{
if (error != NULL)
{
diff --git a/src/goabackend/goaoauthprovider.c b/src/goabackend/goaoauthprovider.c
index a33d6a2..59468ec 100644
--- a/src/goabackend/goaoauthprovider.c
+++ b/src/goabackend/goaoauthprovider.c
@@ -1038,7 +1038,8 @@ goa_oauth_provider_add_account (GoaProvider *_provider,
gchar *identity;
gchar *presentation_identity;
AddData data;
- GVariantBuilder builder;
+ GVariantBuilder credentials;
+ GVariantBuilder details;
g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL);
g_return_val_if_fail (GOA_IS_CLIENT (client), NULL);
@@ -1080,17 +1081,31 @@ goa_oauth_provider_add_account (GoaProvider *_provider,
&data.error))
goto out;
+ g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&credentials, "{sv}", "access_token", g_variant_new_string (access_token));
+ g_variant_builder_add (&credentials, "{sv}", "access_token_secret", g_variant_new_string (access_token_secret));
+ if (access_token_expires_in > 0)
+ g_variant_builder_add (&credentials, "{sv}", "access_token_expires_at",
+ g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
+ if (session_handle != NULL)
+ g_variant_builder_add (&credentials, "{sv}", "session_handle", g_variant_new_string (session_handle));
+ if (session_handle_expires_in > 0)
+ g_variant_builder_add (&credentials, "{sv}", "session_handle_expires_at",
+ g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in)));
+
+ g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
+ goa_oauth_provider_add_account_key_values (provider, &details);
+
/* we want the GoaClient to update before this method returns (so it
* can create a proxy for the new object) so run the mainloop while
* waiting for this to complete
*/
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
- goa_oauth_provider_add_account_key_values (provider, &builder);
goa_manager_call_add_account (goa_client_get_manager (client),
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
identity,
presentation_identity,
- g_variant_builder_end (&builder),
+ g_variant_builder_end (&credentials),
+ g_variant_builder_end (&details),
NULL, /* GCancellable* */
(GAsyncReadyCallback) add_account_cb,
&data);
@@ -1101,25 +1116,6 @@ goa_oauth_provider_add_account (GoaProvider *_provider,
ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
data.account_object_path));
- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
- g_variant_builder_add (&builder, "{sv}", "access_token", g_variant_new_string (access_token));
- g_variant_builder_add (&builder, "{sv}", "access_token_secret", g_variant_new_string (access_token_secret));
- if (access_token_expires_in > 0)
- g_variant_builder_add (&builder, "{sv}", "access_token_expires_at",
- g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
- if (session_handle != NULL)
- g_variant_builder_add (&builder, "{sv}", "session_handle", g_variant_new_string (session_handle));
- if (session_handle_expires_in > 0)
- g_variant_builder_add (&builder, "{sv}", "session_handle_expires_at",
- g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in)));
- /* TODO: run in worker thread */
- if (!goa_utils_store_credentials_sync (GOA_PROVIDER (provider),
- ret,
- g_variant_builder_end (&builder),
- NULL, /* GCancellable */
- &data.error))
- goto out;
-
out:
/* We might have an object even when data.error is set.
* eg., if we failed to store the credentials in the keyring.
@@ -1219,11 +1215,11 @@ goa_oauth_provider_refresh_account (GoaProvider *_provider,
g_variant_builder_add (&builder, "{sv}", "session_handle_expires_at",
g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in)));
/* TODO: run in worker thread */
- if (!goa_utils_store_credentials_sync (GOA_PROVIDER (provider),
- object,
- g_variant_builder_end (&builder),
- NULL, /* GCancellable */
- error))
+ if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
+ object,
+ g_variant_builder_end (&builder),
+ NULL, /* GCancellable */
+ error))
goto out;
goa_account_call_ensure_credentials (goa_object_peek_account (object),
@@ -1446,11 +1442,11 @@ goa_oauth_provider_get_access_token_sync (GoaOAuthProvider *provider,
g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in)));
/* TODO: run in worker thread */
- if (!goa_utils_store_credentials_sync (GOA_PROVIDER (provider),
- object,
- g_variant_builder_end (&builder),
- cancellable,
- error))
+ if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
+ object,
+ g_variant_builder_end (&builder),
+ cancellable,
+ error))
{
if (error != NULL)
{
diff --git a/src/goabackend/goautils.c b/src/goabackend/goautils.c
index 9d00130..b937475 100644
--- a/src/goabackend/goautils.c
+++ b/src/goabackend/goautils.c
@@ -226,21 +226,20 @@ goa_utils_lookup_credentials_sync (GoaProvider *provider,
}
gboolean
-goa_utils_store_credentials_sync (GoaProvider *provider,
- GoaObject *object,
- GVariant *credentials,
- GCancellable *cancellable,
- GError **error)
+goa_utils_store_credentials_for_id_sync (GoaProvider *provider,
+ const gchar *id,
+ GVariant *credentials,
+ GCancellable *cancellable,
+ GError **error)
{
gboolean ret;
gchar *credentials_str;
gchar *password_description;
gchar *password_key;
GnomeKeyringResult result;
- const gchar *identity;
g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
- g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
+ g_return_val_if_fail (id != NULL && id[0] != '\0', FALSE);
g_return_val_if_fail (credentials != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -248,8 +247,6 @@ goa_utils_store_credentials_sync (GoaProvider *provider,
/* TODO: use GCancellable */
ret = FALSE;
- identity = goa_account_get_id (goa_object_peek_account (object));
-
credentials_str = g_variant_print (credentials, TRUE);
g_variant_ref_sink (credentials);
g_variant_unref (credentials);
@@ -257,11 +254,11 @@ goa_utils_store_credentials_sync (GoaProvider *provider,
password_key = g_strdup_printf ("%s:gen%d:%s",
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
- identity);
+ id);
/* Translators: The %s is the type of the provider, e.g. 'google' or 'yahoo' */
password_description = g_strdup_printf (_("GOA %s credentials for identity %s"),
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
- identity);
+ id);
result = gnome_keyring_store_password_sync (&keyring_password_schema,
NULL, /* default keyring */
password_description,
@@ -286,3 +283,22 @@ goa_utils_store_credentials_sync (GoaProvider *provider,
g_free (password_description);
return ret;
}
+
+gboolean
+goa_utils_store_credentials_for_object_sync (GoaProvider *provider,
+ GoaObject *object,
+ GVariant *credentials,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *id;
+
+ g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
+ g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
+ g_return_val_if_fail (credentials != NULL, FALSE);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ id = goa_account_get_id (goa_object_peek_account (object));
+ return goa_utils_store_credentials_for_id_sync (provider, id, credentials, cancellable, error);
+}
diff --git a/src/goabackend/goautils.h b/src/goabackend/goautils.h
index 343c8f4..406de34 100644
--- a/src/goabackend/goautils.h
+++ b/src/goabackend/goautils.h
@@ -53,11 +53,17 @@ GVariant *goa_utils_lookup_credentials_sync (GoaProvider *provider,
GCancellable *cancellable,
GError **error);
-gboolean goa_utils_store_credentials_sync (GoaProvider *provider,
- GoaObject *object,
- GVariant *credentials,
- GCancellable *cancellable,
- GError **error);
+gboolean goa_utils_store_credentials_for_id_sync (GoaProvider *provider,
+ const gchar *id,
+ GVariant *credentials,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean goa_utils_store_credentials_for_object_sync (GoaProvider *provider,
+ GoaObject *object,
+ GVariant *credentials,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]